第3章 XML を使用したメタデータのオーバーライド

EJB3 のメタデータに対するプライマリターゲットはアノテーションですが、EJB3 仕様では XML デプロイメント記述子を使用してアノテーションで定義されたメタデータをオーバーライドまたは置換できます。現在のリリースでは、純粋な EJB3 アノテーションのオーバーライドのみがサポートされます。一部のエンティティで Hibernate 固有の機能を使用する場合は、アノテーションまたは hbm ファイルのフォールバックを使用する必要があります。ただし、アノテートされたエンティティと hbm ファイルで定義されたエンティティを組み合わせたり、一致させたりできます。
ユニットテストスイートはいくつかの追加 XML ファイルサンプルを示します。

3.1. 原則

XML デプロイメント記述子構造は、アノテーション構造を反映するよう設計されています。したがって、アノテーション構造を知っている場合は、XML スキーマを使用することが簡単です。
メタデータを定義する 1 つまたは複数の XML ファイルを定義できます。これらのファイルはオーバーライドエンジンによってマージされます。

3.1.1. グローバルレベルメタデータ

すべての XML ファイルで利用可能なグローバルレベルメタデータを定義できます。これらのメタデータをデプロイメントごとに複数回定義しないでください。
<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings 
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
  version="1.0">

    <persistence-unit-metadata>
        <xml-mapping-metadata-complete/>
        <persistence-unit-defaults>
            <schema>myschema</schema>
            <catalog>mycatalog</catalog>
            <cascade-persist/>
        </persistence-unit-defaults>
    </persistence-unit-metadata>
xml-mapping-metadata-complete は、すべてのエンティティ、マップされたスーパークラス、および組み込み可能なメタデータを XML から取得することを意味します (つまり、アノテーションを無視します)。
schema / catalog はメタデータのスキーマとカタログの全デフォルト定義をオーバーライドします (XML とアノテーションの両方)。
cascade-persist は、すべての関係がカスケードタイプとして PERSIST を持つことを意味します。この機能を使用しないことを推奨します。

3.1.2. エンティティレベルメタデータ

該当するエンティティでメタデータ情報を定義またはオーバーライドできます。
<?xml version="1.0" encoding="UTF-8"?>
 
<entity-mappings                                                                      1
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
  version="1.0">
 
    <package>org.hibernate.test.annotations.reflection</package>                      2
    <entity class="Administration" access="PROPERTY" metadata-complete="true">        3
        <table name="tbl_admin">                                                      4
            <unique-constraint>
                <column-name>firstname</column-name>
                <column-name>lastname</column-name>
            </unique-constraint>
        </table>
        <secondary-table name="admin2">                                               5
            <primary-key-join-column name="admin_id" referenced-column-name="id"/>
            <unique-constraint>
                <column-name>address</column-name>
            </unique-constraint>
        </secondary-table>
        <id-class class="SocialSecurityNumber"/>                                      6
        <inheritance strategy="JOINED"/>                                              7
        <sequence-generator name="seqhilo" sequence-name="seqhilo"/>                  8
        <table-generator name="table" table="tablehilo"/>                             9
        ...
    </entity>
 
    <entity class="PostalAdministration">
        <primary-key-join-column name="id"/>                                          10
        ...
    </entity>
</entity-mappings>

1

entity-mappings: entity-mappings はすべての XML ファイルのルートエレメントです。xml スキーマを宣言する必要があります。スキーマファイルは hibernate-annotations.jar ファイルに含まれます。Hibernate Annotations によってインターネットアクセスは処理されません。

2

package (オプション): 該当するデプロイメント記述子ファイルのすべての非修飾クラス名に使用されたデフォルトパッケージ。

3

entity: エンティティを表します。
metadata-complete はこのエレメントのメタデータ記述が完全であるかどうかを定義します (つまり、クラスレベルで存在するアノテーションを考慮すべきかどうか)。
エンティティが必ず持つclass 属性は、メタデータが適用される java クラスを参照する必要があります。
name 属性を使用してエンティティ名をオーバーライドできます。何も定義されていない場合や、@Entity.name が存在する場合に使用されます (metadata completeが設定されていない場合)。
metadata complete (以下参照) エレメントの場合は、access (FIELD または PROPERTY (デフォルト値)) を定義できます。metadata completeエレメント以外の場合は、access が定義されていないときに @Id 位置が位置を主導し、access が定義されているときに値が使用されます。

4

table: テーブルプロパティ (名前、スキーマ、カタログ) を宣言できます。何も定義されていない場合は、java アノテーションが使用されます。
例で示されたように 1 つまたは複数の一意の制約を定義できます。

5

secondary-table: 通常のテーブルと同様にセカンダリテーブルを定義します (ただし、primary-key-join-column エレメントを使用してプライマリキー/外部キーカラムを定義できます)。完全な非メタデータでは、アノテーションセカンダリテーブルは secondary-table 定義が存在しない場合にのみ使用されます。それ以外の場合、アノテーションは無視されます。

6

id-class: @IdClass の場合と同様に ID クラスを定義します。

7

inheritance: 階層方針 (JOINEDTABLE_PER_CLASSSINGLE_TABLE) を定義します。ルートエンティティレベルでのみ利用可能です。

8

sequence-generator: シーケンスジェネレータを定義します。

9

table-generator: テーブルジェネレータを定義します。

10

primary-key-join-column: JOINED 継承方針が使用された場合にサブエンティティのプライマリキー結合カラムを定義します。
<?xml version="1.0" encoding="UTF-8"?>
 
<entity-mappings 
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
  version="1.0">
 
    <package>org.hibernate.test.annotations.reflection</package>
    <entity class="Music" access="PROPERTY" metadata-complete="true">
        <discriminator-value>Generic</discriminator-value>                           1
        <discriminator-column length="34"/>
        ...
    </entity>
 
    <entity class="PostalAdministration">
        <primary-key-join-column name="id"/>
        <named-query name="adminById">                                               2
            <query>select m from Administration m where m.id = :id</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-query>
        <named-native-query name="allAdmin" result-set-mapping="adminrs">            3
            <query>select *, count(taxpayer_id) as taxPayerNumber 
            from Administration, TaxPayer
            where taxpayer_admin_id = admin_id group by ...</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-native-query>
        <sql-result-set-mapping name="adminrs">                                      4
            <entity-result entity-class="Administration">
                <field-result name="name" column="fld_name"/>
            </entity-result>
            <column-result name="taxPayerNumber"/>
        </sql-result-set-mapping>
        <attribute-override name="ground">                                           5
            <column name="fld_ground" unique="true" scale="2"/>
        </attribute-override>
        <association-override name="referer">
            <join-column name="referer_id" referenced-column-name="id"/>
        </association-override>
        ...
    </entity>
</entity-mappings>

1

discriminator-value / discriminator-column: SINGLE_TABLE 継承方針が選択された場合に判別子の値とその値を保持するカラムを定義します。

2

named-query: 名前付きクエリとクエリに関連するヒントを定義します。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

3

named-native-query: 名前付きネイティブクエリとその SQL 結果セットマッピングを定義します。または、result-class を定義できます。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

4

sql-result-set-mapping: 結果セットマッピング構造を定義します。エンティティとカラム両方のマッピングを定義できます。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

5

attribute-override / association-override: カラムまたは結合カラムオーバーライドを定義します。このオーバーライドはアノテーションで定義されたものに追加されます。
同じことは <embeddable> and <mapped-superclass> にも適用されます。

3.1.3. プロパティレベルメタデータ

プロパティの XML オーバーライドを定義することはもちろんできます。metadata completeが定義された場合は、追加プロパティ (Java レベル) が無視されます。それ以外の場合は、プロパティのオーバーライドが開始されると、該当するプロパティのすべてのアノテーションが無視されます。すべてのプロパティレベルメタデータは entity/attributesmapped-superclass/attributes、または embeddable/attributes に存在します。
    <attributes>
        <id name="id">
            <column name="fld_id"/>
            <generated-value generator="generator" strategy="SEQUENCE"/>
            <temporal>DATE</temporal>
            <sequence-generator name="generator" sequence-name="seq"/>
        </id>
        <version name="version"/>
        <embedded name="embeddedObject">
            <attribute-override name"subproperty">
                <column name="my_column"/>
            </attribute-override>
        </embedded>
        <basic name="status" optional="false">
            <enumerated>STRING</enumerated>
        </basic>
        <basic name="serial" optional="true">
            <column name="serialbytes"/>
            <lob/>
        </basic>
        <basic name="terminusTime" fetch="LAZY">
            <temporal>TIMESTAMP</temporal>
        </basic>
    </attributes>
idembedded-idversionembedded、および basic を使用してプロパティをオーバーライドできます。これらの各エレメントは適切なサブエレメントを持ちます (lobtemporalenumeratedcolumn)。

3.1.4. 関係レベルメタデータ

関係に対してe XMLオーバーライドを定義できます。すべての関係レベルメタデータがentity/attributesmapped-superclass/attributes、または embeddable/attributes で動作します。
    <attributes>
        <one-to-many name="players" fetch="EAGER">
            <map-key name="name"/>
            <join-column name="driver"/>
            <join-column name="number"/>
        </one-to-many>
        <many-to-many name="roads" target-entity="Administration">
            <order-by>maxSpeed</order-by>
            <join-table name="bus_road">
                <join-column name="driver"/>
                <join-column name="number"/>
                <inverse-join-column name="road_id"/>
                <unique-constraint>
                    <column-name>driver</column-name>
                    <column-name>number</column-name>
                </unique-constraint>
            </join-table>
        </many-to-many>
        <many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
    </attributes>
one-to-manyone-to-onemany-to-one、および many-to-many を使用して関係をオーバーライドできます。これらの各エレメントは適切なサブエレメント (join-table (join-columninverse-join-column を持つことができる)、join-columnmap-key、および order-by) を持つことができます。mapped-bytarget-entity は属性として定義できます (適切な場合)。構造がアノテーション構造を再び反映します。すべてのセマンティック情報については、アノテーションを説明する章を参照してください。