30.11. エンティティコマンドおよびプライマリキー生成
永続ストアにエンティティを挿入するのに使用するエンティティ作成コマンドオブジェクトをカスタム実装することで、エンティティ bean 外でのプライマリキー生成に対応するようになりました。利用可能なコマンドのリストは、
jbosscmp-jdbc.xml 記述子の entity-command 要素で指定します。デフォルトの entity-command は、jbosscmp-jdbc.xml の defaults 要素で指定できます。それぞれの entity 要素では、 独自の entity-commandを指定することによって、デフォルトの entity-commandをオーバーライドすることができます。entity-commandおよび子要素のコンテンツモデルを次に示します。

図30.15 jbosscmp-jdbc.xml entity-command 要素モデル
各
entity-command 要素では、エンティティ生成実装を指定します。name 属性では、entity-commands セクションで定義されたコマンドを defaults および entity 要素で参照できるようにする名前を指定します。class 属性では、キー生成をサポートする org.jboss.ejb.plugins.cmp.jdbc 実装を指定します。データベースベンダー固有のコマンドは通常、挿入実行の副次的結果としてデータベースがプライマリキーを生成する場合は org.jboss.ejb.plugins.cmp.jdbc。JDBCIdentityColumnCreateCommand を、生成されたキーをコマンドで挿入しなければならない場合は org.jboss.ejb.plugins.cmp.jdbc.JDBCInsertPKCreateCommand をサブクラス化します。
オプションの
attribute 属性は、エンティティコマンド実装クラスに対して利用可能になる任意名/値プロパティペアの指定を可能にするものです。attribute 属性には、名前プロパティを指定する必須の name 属性があり、attribute 属性のコンテンツはプロパティの値です。属性値は、org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityCommandMetaData.getAttribute(文字列) メソッドを使いアクセスすることができます。
30.11.1. 既存のエンティティコマンド
以下は、
standardjbosscmp-jdbc.xml 記述子内にある現行の entity-command 定義です。
- default: (
org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand)JDBCCreateEntityCommandは、standardjbosscmp-jdbc.xmldefaults 要素で参照されるentity-commandであるため、デフォルトの要素作成になります。この entity-command は、割り当てられたプライマリキー値を使用してINSERT INTOクエリーを実行します。 - no-select-before-insert: (
org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand) これは、jboss.jdbc:service=SQLExceptionProcessorサービスをポイントする属性name="SQLExceptionProcessor"を指定することによって insert の select をスキップするdefaultの変化形です。SQLExceptionProcessorサービスは、boolean isDuplicateKey(SQLException e)操作を提供し、一意制約違反がないか判断することができるようになります。 - pk-sql (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPkSqlCreateCommand)JDBCPkSqlCreateCommandは、pk-sql属性により与えられるINSERT INTOクエリーステートメントを実行して、 次のプライマリキー値を取得します。 シーケンスサポートのあるデータベースが主要な使用目的です。 - mysql-get-generated-keys: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCMySQLCreateCommand)JDBCMySQLCreateCommandは、 MySQL ネイティブjava.sql.Statementインターフェース実装からgetGeneratedKeysメソッドを使用してINSERT INTOクエリーを実行し生成されたキーをフェッチします。 - oracle-sequence: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCOracleCreateCommand)JDBCOracleCreateCommandは、RETURNING句とともにシーケンスを使用して単一のステートメントでキーを生成する、Oracle と併用する作成コマンドです。これには、シーケンスのカラム名を指定する必須のsequence要素があります。 - hsqldb-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCHsqldbCreateCommand)JDBCHsqldbCreateCommandは、CALL IDENTITY()ステートメントの実行後にINSERT INTOクエリーを実行して生成されたキーをフェッチします。 - sybase-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSybaseCreateCommand)JDBCSybaseCreateCommandは、SELECT @@IDENTITYステートメントの実行後にINSERTINTO クエリーを実行して生成されたキーをフェッチします。 - mssql-fetch-key: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSQLServerCreateCommand)IDENTITYカラムからの値を使用する Microsoft SQL Server 用のJDBCSQLServerCreateCommandです。デフォルトでは、SELECT SCOPE_IDENTITY()を使用して、トリガーの影響を減らします。たとえば V7 などのpk-sql属性でオーバーライドできます。 - informix-serial: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCInformixCreateCommand)JDBCInformixCreateCommandは、 Informix ネイティブjava.sql.Statementインターフェース実装からgetSerialメソッドを使用した後でINSERTINTO クエリーを実行して生成されたキーをフェッチします。 - postgresql-fetch-seq: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPostgreSQLCreateCommand) シーケンスの現在値をフェッチする PostgreSQL 用のJDBCPostgreSQLCreateCommandです。オプションのsequence属性を使用して、シーケンス名を変更することができます。デフォルトはtable_pkColumn_seqです。 - key-generator: (
org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCKeyGeneratorCreateCommand)JDBCKeyGeneratorCreateCommandは、key-generator-factoryにより参照されるキージェネレーターからプライマリキーの値を取得した後にINSERT INTOクエリーを実行します。key-generator-factory属性ではorg.jboss.ejb.plugins.keygenerator.KeyGeneratorFactory実装の JNDI バインディングの名前を指定しなければなりません。 - get-generated-keys: (org.jboss.ejb.plugins.cmp.jdbc.jdbc3.JDBCGetGeneratedKeysCreateCommand)
JDBCGetGeneratedKeysCreateCommandは、自動生成されたキーを取り出す機能を持つprepareStatement(String, Statement.RETURN_GENERATED_KEYS)を使用して構築されたステートメントを使用してINSERT INTOクエリーを実行します。生成されたキーは、PreparedStatement.getGeneratedKeysメソッドを呼び出すことによって得られます。これは JDBC3 サポートが必要なため、サポートする JDBC ドライバーがある JDK1.4.1+ でのみ利用可能です。
生成されたキーが既知のプライマリキー
cmp-field にマッピングされる、hsqldb-fetch-keyentity-command を使用した設定例を次に示します。
<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>
明示的な
cmp-field なしに不明なプライマリキーを使用した別例を次に示します。
<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>