Red Hat Training

A Red Hat training course is available for Red Hat JBoss Web Server

9.4. 複合識別子としてのコンポーネント

コンポーネントをエンティティクラスの識別子として使うことができます。コンポーネントクラスは一定の条件を満たす必要があります。
  • java.io.Serializable を実装しなければなりません。
  • データベース上の複合キーの等価性と矛盾のないように、equals()hashCode() を再実装しなければなりません。

注記

Hibernate3 において、2番目の条件は絶対的な条件ではありませんが、推奨はされています。
複合キーを生成するために IdentifierGenerator を使用することはできません。代わりにアプリケーションが独自の識別子を割り当てなくてはなりません。
通常の <id> 宣言の代わりに <composite-id> タグをネストされた <key-property> 属性と共に使います。例えば、OrderLine クラスは Order の(複合)主キーに依存した主キーを持っています。
<class name="OrderLine">
    
    <composite-id name="id" class="OrderLineId">
        <key-property name="lineId"/>
        <key-property name="orderId"/>
        <key-property name="customerId"/>
    </composite-id>
    
    <property name="name"/>
    
    <many-to-one name="order" class="Order"
            insert="false" update="false">
        <column name="orderId"/>
        <column name="customerId"/>
    </many-to-one>
    ....
    
</class>
このとき、OrderLine テーブルへ関連する外部キーもまた複合です。他のクラスのマッピングでこれを宣言しなければなりません。 OrderLine への関連は次のようにマッピングされます。
<many-to-one name="orderLine" class="OrderLine">
<!-- the "class" attribute is optional, as usual -->
    <column name="lineId"/>
    <column name="orderId"/>
    <column name="customerId"/>
</many-to-one>

注記

<column> タグはどこも column 属性の代わりになります。
OrderLine への many-to-many 関連も複合外部キーを使います。
<set name="undeliveredOrderLines">
    <key column name="warehouseId"/>
    <many-to-many class="OrderLine">
        <column name="lineId"/>
        <column name="orderId"/>
        <column name="customerId"/>
    </many-to-many>
</set>
Order にある OrderLine のコレクションは次のものを使用します:
<set name="orderLines" inverse="true">
    <key>
        <column name="orderId"/>
        <column name="customerId"/>
    </key>
    <one-to-many class="OrderLine"/>
</set>
<one-to-many> 属性はカラムを宣言しません。
OrderLine 自身がコレクションを持っている場合、同時に複合外部キーも持っています。
<class name="OrderLine">
    ....
    ....
    <list name="deliveryAttempts">
        <key>   <!-- a collection inherits the composite key type -->
            <column name="lineId"/>
            <column name="orderId"/>
            <column name="customerId"/>
        </key>
        <list-index column="attemptId" base="1"/>
        <composite-element class="DeliveryAttempt">
            ...
        </composite-element>
    </set>
</class>