30.11. エンティティコマンドおよびプライマリキー生成

永続ストアにエンティティを挿入するのに使用するエンティティ作成コマンドオブジェクトをカスタム実装することで、エンティティ bean 外でのプライマリキー生成に対応するようになりました。利用可能なコマンドのリストは、jbosscmp-jdbc.xml 記述子の entity-command 要素で指定します。デフォルトの entity-command は、jbosscmp-jdbc.xml の defaults 要素で指定できます。それぞれの entity 要素では、 独自の entity-commandを指定することによって、デフォルトの entity-commandをオーバーライドすることができます。entity-commandおよび子要素のコンテンツモデルを次に示します。
jbosscmp-jdbc.xml 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.jdbcJDBCIdentityColumnCreateCommand を、生成されたキーをコマンドで挿入しなければならない場合は 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.xml defaults 要素で参照される 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 ステートメントの実行後に INSERT INTO クエリーを実行して生成されたキーをフェッチします。
  • 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 メソッドを使用した後で INSERT INTO クエリーを実行して生成されたキーをフェッチします。
  • 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>