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.
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
) TheJDBCCreateEntityCommand
is the default entity creation as it is theentity-command
referenced in thestandardjbosscmp-jdbc.xml
defaults element. This entity-command executes anINSERT INTO
query using the assigned primary key value. - no-select-before-insert: (
org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand
) This is a variation ondefault
that skips select before insert by specifying an attributename="SQLExceptionProcessor"
that points to thejboss.jdbc:service=SQLExceptionProcessor
service. TheSQLExceptionProcessor
service provides aboolean isDuplicateKey(SQLException e)
operation that allows a for determination of any unique constraint violation. - pk-sql (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPkSqlCreateCommand
) TheJDBCPkSqlCreateCommand
executes anINSERT INTO
query statement provided by thepk-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
) TheJDBCMySQLCreateCommand
executes anINSERT INTO
query using thegetGeneratedKeys
method from MySQL nativejava.sql.Statement
interface implementation to fetch the generated key. - oracle-sequence: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCOracleCreateCommand
) TheJDBCOracleCreateCommand
is a create command for use with Oracle that uses a sequence in conjunction with aRETURNING
clause to generate keys in a single statement. It has a requiredsequence
element that specifies the name of the sequence column. - hsqldb-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCHsqldbCreateCommand
) TheJDBCHsqldbCreateCommand
executes anINSERT INTO
query after executing aCALL IDENTITY()
statement to fetch the generated key. - sybase-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSybaseCreateCommand
) TheJDBCSybaseCreateCommand
executes anINSERT
INTO query after executing aSELECT @@IDENTITY
statement to fetch the generated key. - mssql-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSQLServerCreateCommand
) TheJDBCSQLServerCreateCommand
for Microsoft SQL Server that uses the value from anIDENTITY
columns. By default usesSELECT SCOPE_IDENTITY()
to reduce the impact of triggers; can be overridden withpk-sql
attribute e.g. for V7. - informix-serial: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCInformixCreateCommand
) TheJDBCInformixCreateCommand
executes anINSERT
INTO query after using thegetSerial
method from Informix nativejava.sql.Statement
interface implementation to fetch the generated key. - postgresql-fetch-seq: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPostgreSQLCreateCommand
) TheJDBCPostgreSQLCreateCommand
for PostgreSQL that fetches the current value of the sequence. The optionalsequence
attribute can be used to change the name of the sequence, with the default beingtable_pkColumn_seq
. - key-generator: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCKeyGeneratorCreateCommand
) TheJDBCKeyGeneratorCreateCommand
executes anINSERT INTO
query after obtaining a value for the primary key from the key generator referenced by thekey-generator-factory
. Thekey-generator-factory
attribute must provide the name of a JNDI binding of theorg.jboss.ejb.plugins.keygenerator.KeyGeneratorFactory
implementation. - get-generated-keys: (org.jboss.ejb.plugins.cmp.jdbc.jdbc3.JDBCGetGeneratedKeysCreateCommand) The
JDBCGetGeneratedKeysCreateCommand
executes anINSERT INTO
query using a statement built using the JDBC3prepareStatement(String, Statement.RETURN_GENERATED_KEYS)
that has the capability to retrieve the auto-generated key. The generated key is obtained by calling thePreparedStatement.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-key
entity-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>