Red Hat Training
A Red Hat training course is available for Red Hat JBoss Web Server
9.2. 依存オブジェクトのコレクション
Hibernate はコンポーネントのコレクションをサポートしています(例えば
Name
型の配列)。<element>
タグを <composite-element>
タグに置き換えることでコンポーネントコレクションを宣言してください。
<set name="someNames" table="some_names" lazy="true"> <key column="id"/> <composite-element class="eg.Name"> <!-- class attribute required --> <property name="initial"/> <property name="first"/> <property name="last"/> </composite-element> </set>
重要
複合要素の
Set
を定義する場合、 equals()
と hashCode()
を正しく実装することが重要です。
複合要素はコレクションではなく、コンポーネントを含むこともあります。複合要素自身がコンポーネントを含んでいる場合は
<nested-composite-element>
タグを使用してください。これは、コンポーネントのコレクション自身がコンポーネントを持つケースです。この段階までに、one-to-many 関連の方がより適切でないかと熟考してください。コンポジットエレメントをエンティティとして再度モデリングしてみてください。しかしこれは Java のモデルとしては同じでもリレーショナルモデルと永続動作はまだ若干異なることに注意してください。
<set>
を使用する場合、複合要素のマッピングが null の代入可能なプロパティには対応していません。複合要素テーブルには別の主キーカラムがありません。Hibernate はオブジェクトの削除時、レコードを識別するために各カラムの値を使用する必要があるため、null 値を持つことが出来ません。複合要素に not-null の属性のみを使用するか、または <list>
、<map>
、<bag>
、<idbag>
を選択する必要があります。
複合要素の特別なケースとして、ネストされた
<many-to-one>
属性を持つ複合要素があります。このマッピングは、複合要素クラスを多対多関連テーブルの余分なカラムへマッピングします。以下は、Order
から、Item
への多対多関連で、purchaseDate
、price
、quantity
が関連のプロパティとなっています。
<class name="eg.Order" .... > .... <set name="purchasedItems" table="purchase_items" lazy="true"> <key column="order_id"> <composite-element class="eg.Purchase"> <property name="purchaseDate"/> <property name="price"/> <property name="quantity"/> <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional --> </composite-element> </set> </class>
双方向関連のナビゲーションに反対側から purchase への参照を作ることは出来ません。コンポーネントは値型であり、共有参照ができません。一つの
Purchase
は一つの Order
の set に存在できますが、同時にその Item
による参照することは出来ません。
3項関連(あるいは4項など)も可能です。
<class name="eg.Order" .... > .... <set name="purchasedItems" table="purchase_items" lazy="true"> <key column="order_id"> <composite-element class="eg.OrderLine"> <many-to-one name="purchaseDetails class="eg.Purchase"/> <many-to-one name="item" class="eg.Item"/> </composite-element> </set> </class>
複合要素は他のエンティティへの関連として、同じ構文を用いるクエリ内で出現可能です。