30.5.3. 関係マッピング

リレーションシップは外部キー、または別の関係テーブルを使ってマッピングできます。1 対 1、および 1 対多のリレーションシップはデフォルトで外部キーマッピングスタイルを使用し、多対多のリレーションシップではリレーションテーブルマッピングスタイルのみを使用します。リレーションシップのマッピングは ejb-relation 要素を使い jbosscmp-jdbc.xml 記述子の relationships セクションで宣言します。リレーションシップは ejb-jar.xml ファイルの ejb-relation-name で識別されます。jbosscmp-jdbc.xmlejb-relation 要素のコンテンツモデルを図30.7「jbosscmp-jdbc.xml ejb-relation 要素のコンテンツモデル」
jbosscmp-jdbc.xml ejb-relation 要素のコンテンツモデル

図30.7 jbosscmp-jdbc.xml ejb-relation 要素のコンテンツモデル

Organization-Gangster リレーションシップのリレーションシップマッピング宣言の基本テンプレートは次のようになります。
<jbosscmp-jdbc>
    <relationships>
        <ejb-relation>
            <ejb-relation-name>Organization-Gangster</ejb-relation-name>
            <foreign-key-mapping/>
            <ejb-relationship-role>
                <ejb-relationship-role-name>org-has-gangsters</ejb-relationship-role-name>
                <key-fields>
                    <key-field>
                        <field-name>name</field-name>
                        <column-name>organization</column-name>
                    </key-field>
                </key-fields>
            </ejb-relationship-role>
            <ejb-relationship-role>
                <ejb-relationship-role-name>gangster-belongs-to-org</ejb-relationship-role-name>
                <key-fields/>
            </ejb-relationship-role>
        </ejb-relation>
    </relationships>
</jbosscmp-jdbc>
マッピングされるリレーションシップの ejb-relation-name を宣言すれば、リレーションシップはread-onlyread-time-out 要素を使用して読み取り専用として宣言することができます。これはエンティティ要素の相手側と同じセマンティクスを持ちます。
ejb-relation 要素は foreign-key-mapping 要素、または relation-table-mapping 要素を含む必要があります。詳しくは 「外部キーマッピング」 および 「関係テーブルのマッピング」 に説明します。次のセクションに説明するように、このエレメントは ejb-relationship-role 要素のペアも含みます。

30.5.3.1. リレーションシップロールマッピング

2 つの ejb-relationship-role 要素はそれぞれリレーションシップのエンティティ特有のマッピング情報を含みます。ejb-relationship-role 要素のコンテンツモデルを 図30.8「jbosscmp-jdbc ejb-relationship-role 要素のコンテンツモデル」に示します。
jbosscmp-jdbc ejb-relationship-role 要素のコンテンツモデル

図30.8 jbosscmp-jdbc ejb-relationship-role 要素のコンテンツモデル

主な要素の詳細は次の通りになります。
  • ejb-relationship-role-name: 必須であるこの要素は、この設定が適用されるロール名を付与します。名称はejb-jar.xml ファイルでこのリレーションシップに対して宣言されたロールのうち一つの名称と一致させる必要があります。
  • fk-constraint: この任意の要素は true/false の値で、リレーションシップのこちら側のテーブルに対して外部キー制約を追加するかどうか示すものです。デプロイメント実行中に JBoss がプライマリテーブルとこのプライマリテーブルに関連するテーブルを両方作成した場合、JBoss は制約のみを追加生成します。
  • key-fields: 現行エンティティのプライマリキーフィールドのマッピングについて、関係テーブル、または関連するオブジェクトのいずれにマッピングするかを指定します。key-fields 要素は、現在のエンティティのプライマリキーフィールドごとに key-fields 要素を1つ含む必要があります。リレーションのこちら側に外部キーマッピングが必要なければ、key-fields 要素を空にしておくこともできます。この例は、1 対多のリレーションシップの多サイドになります。この要素の詳細については以下に説明します。
  • read-ahead: この任意の要素は、リレーションシップのキャッシュを制御します。このオプションについては、「リレーションシップ」で説明します。
  • batch-cascade-delete: このリレーションシップにおけるカスケード削除は、SQL ステートメント1つで実行しなければならないことを示します。この場合、このリレーションシップは ejb-jar.xmlbatch-delete としてマークしておく必要があります。
上記で述べたように、 key-fields 要素は、現行のエンティティのプライマリキーフィールドごとに key-fields 要素を1つ含みます。key-field 要素は、エンティティの cmp-field 要素と同じ構文を使います。ただし、key-fieldnot-null オプションをサポートしません。relation-table のキーフィールドはテーブルのプライマリキーなので、自動的に not null になります。一方で、外部キーフィールドはデフォルトで null 可能にしておく必要があります。CMP 仕様は ejbPostCreateメソッドによってデータベースに挿入し、ejbPostCreateによる CMR の変更箇所をピックアップするため、更新する必要があります。EJB 仕様では ejbPostCreateまではリレーションシップを修正できないため、外部キーは最初は null に設定されます。削除の場合にも同様の問題が発生します。この挿入動作は jboss.xmlinsert-after-ejb-post-create コンテナー設定フラグを使用して変更することもできます。デフォルトで insert-after-ejb-post-create を使用する新しい bean 設定の作成を以下の例に示します。
<jboss>
    <!-- ... -->
    <container-configurations>
        <container-configuration extends="Standard CMP 2.x EntityBean">
            <container-name>INSERT after ejbPostCreate Container</container-name>
            <insert-after-ejb-post-create>true</insert-after-ejb-post-create>
        </container-configuration>
    </container-configurations>                     
</jboss>
non-null の外部キーを操作するには、non-null の CMP フィールドに外部キー要素をマッピングする方法もあります。この場合、関連する CMP フィールドセッターを使用して ejbCreate の外部キーフィールドを生成するだけです。
key-fields 要素のコンテンツモデルを 図30.9「jbosscmp-jdbc key-fields 要素のコンテンツモデル」に示します。
jbosscmp-jdbc key-fields 要素のコンテンツモデル

図30.9 jbosscmp-jdbc key-fields 要素のコンテンツモデル

key-field 要素に含まれる各種要素の詳細については、以下に説明します。
  • field-name: この必須要素は、マッピングを適用するフィールドを識別します。この名称は、現行エンティティのプライマリキーフィールドに一致させる必要があります。
  • column-name: プライマリキーフィールドが格納される列の名称を指定する場合、このエレメントを使用します。このリレーションシップが foreign-key-mappingを使用する場合、この列は関連するエンティティのテーブルに追加されます。このリレーションシップが relation-table-mappingを使用する場合、この列は relation-tableに追加されます。この要素はマッピング依存値クラスには対応しません。代わりにプロパティ要素を使用します。
  • jdbc-type: JDBC PreparedStatement内にパラメーターを設定する、または JDBC ResultSet からデータをロードする場合に使用される JDBC タイプです。有効なタイプは java.sql.Typesに定義されます。
  • sql-type: このフィールドの create テーブルステートメントで使用される SQL タイプです。有効なタイプは、データベースベンダーのみにて制限されます。
  • property: 依存値クラスのプライマリキーフィールドのマッピングを指定する場合、この要素を使用します。
  • dbindex: この任意フィールドがあると、サーバーはデータベース内の該当カラムにインデックスを作成する必要があることを示します。このインデックス名は fieldname_index になります。