31.11. Entity Commands and Primary Key Generation

Support for primary key generation outside of the entity bean is available through custom implementations of the entity creation command objects used to insert entities into a persistent store. The list of available commands is specified in entity-commands element of the jbosscmp-jdbc.xml descriptor. The default entity-command may be specified in the jbosscmp-jdbc.xml in defaults element. Each entity element can override the entity-command in defaults by specifying its own entity-command. The content model of the entity-commands and child elements is given below.
The jbosscmp-jdbc.xml entity-commands element model

Figure 31.15. The jbosscmp-jdbc.xml entity-commands element model

Each entity-command element specifies an entity generation implementation. The name attribute specifies a name that allows the command defined in an entity-commands section to be referenced in the defaults and entity elements. The class attribute specifies the implementation of the org.jboss.ejb.plugins.cmp.jdbc. JDBCCreateEntityCommand that supports the key generation. Database vendor specific commands typically subclass the org.jboss.ejb.plugins.cmp.jdbc. JDBCIdentityColumnCreateCommand if the database generates the primary key as a side effect of doing an insert, or the org.jboss.ejb.plugins.cmp.jdbc.JDBCInsertPKCreateCommand if the command must insert the generated key.
The optional attribute element(s) allows for the specification of arbitrary name/value property pairs that will be available to the entity command implementation class. The attribute element has a required name attribute that specifies the name property, and the attribute element content is the value of the property. The attribute values are accessible through the org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityCommandMetaData.getAttribute(String) method.

31.11.1. Existing Entity Commands

The following are the current entity-command definitions found in the standardjbosscmp-jdbc.xml descriptor:
  • default: (org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand) The JDBCCreateEntityCommand is the default entity creation as it is the entity-command referenced in the standardjbosscmp-jdbc.xml defaults element. This entity-command executes an INSERT INTO query using the assigned primary key value.
  • no-select-before-insert: (org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand) This is a variation on default that skips select before insert by specifying an attribute name="SQLExceptionProcessor" that points to the jboss.jdbc:service=SQLExceptionProcessor service. The SQLExceptionProcessor service provides a boolean isDuplicateKey(SQLException e) operation that allows a for determination of any unique constraint violation.
  • pk-sql (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPkSqlCreateCommand) The JDBCPkSqlCreateCommand executes an INSERT INTO query statement provided by the pk-sql attribute to obtain the next primary key value. Its primary target usage are databases with sequence support.
  • mysql-get-generated-keys: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCMySQLCreateCommand) The JDBCMySQLCreateCommand executes an INSERT INTO query using the getGeneratedKeys method from MySQL native java.sql.Statement interface implementation to fetch the generated key.
  • oracle-sequence: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCOracleCreateCommand) The JDBCOracleCreateCommand is a create command for use with Oracle that uses a sequence in conjunction with a RETURNING clause to generate keys in a single statement. It has a required sequence element that specifies the name of the sequence column.
  • hsqldb-fetch-key: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCHsqldbCreateCommand) The JDBCHsqldbCreateCommand executes an INSERT INTO query after executing a CALL IDENTITY() statement to fetch the generated key.
  • sybase-fetch-key: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSybaseCreateCommand) The JDBCSybaseCreateCommand executes an INSERT INTO query after executing a SELECT @@IDENTITY statement to fetch the generated key.
  • mssql-fetch-key: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSQLServerCreateCommand) The JDBCSQLServerCreateCommand for Microsoft SQL Server that uses the value from an IDENTITY columns. By default uses SELECT SCOPE_IDENTITY() to reduce the impact of triggers; can be overridden with pk-sql attribute e.g. for V7.
  • informix-serial: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCInformixCreateCommand) The JDBCInformixCreateCommand executes an INSERT INTO query after using the getSerial method from Informix native java.sql.Statement interface implementation to fetch the generated key.
  • postgresql-fetch-seq: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPostgreSQLCreateCommand) The JDBCPostgreSQLCreateCommand for PostgreSQL that fetches the current value of the sequence. The optional sequence attribute can be used to change the name of the sequence, with the default being table_pkColumn_seq.
  • key-generator: (org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCKeyGeneratorCreateCommand) The JDBCKeyGeneratorCreateCommand executes an INSERT INTO query after obtaining a value for the primary key from the key generator referenced by the key-generator-factory. The key-generator-factory attribute must provide the name of a JNDI binding of the org.jboss.ejb.plugins.keygenerator.KeyGeneratorFactory implementation.
  • get-generated-keys: (org.jboss.ejb.plugins.cmp.jdbc.jdbc3.JDBCGetGeneratedKeysCreateCommand) The JDBCGetGeneratedKeysCreateCommand executes an INSERT INTO query using a statement built using the JDBC3 prepareStatement(String, Statement.RETURN_GENERATED_KEYS) that has the capability to retrieve the auto-generated key. The generated key is obtained by calling the PreparedStatement.getGeneratedKeys method. Since this requires JDBC3 support it is only available in JDK1.4.1+ with a supporting JDBC driver.
An example configuration using the hsqldb-fetch-keyentity-command with the generated key mapped to a known primary key cmp-field is shown below.
<jbosscmp-jdbc>
  <enterprise-beans>
    <entity>
      <ejb-name>LocationEJB</ejb-name>
      <pk-constraint>false</pk-constraint>
      <table-name>location</table-name>
                 
      <cmp-field>
        <field-name>locationID</field-name>
        <column-name>id</column-name>
        <auto-increment/>
      </cmp-field>
      <!-- ... -->
      <entity-command name="hsqldb-fetch-key"/>
                 
    </entity>
  </enterprise-beans>
</jbosscmp-jdbc>
An alternate example using an unknown primary key without an explicit cmp-field is shown below.
<jbosscmp-jdbc>
    <enterprise-beans>
        <entity>
            <ejb-name>LocationEJB</ejb-name>
            <pk-constraint>false</pk-constraint>
            <table-name>location</table-name>
            <unknown-pk>
                <unknown-pk-class>java.lang.Integer</unknown-pk-class>
                <field-name>locationID</field-name>
                <column-name>id</column-name>
                <jdbc-type>INTEGER</jdbc-type>
                <sql-type>INTEGER</sql-type>
                <auto-increment/>
            </unknown-pk>
            <!--...-->
            <entity-command name="hsqldb-fetch-key"/>
        </entity>
    </enterprise-beans>
</jbosscmp-jdbc>