双方向関連 は関連のどちら「側」からでもナビゲーションできます。2種類の双方向関連がサポートされています:
片側が set か bag 、もう片方が単一値です。
両側が set か bag です。
2つの多対多関連で同じデータベーステーブルをマッピングし、片方を inverse として宣言することで、双方向の多対多関連を指定することが出来ます (どちらを inverse に選んだとしても、そちら側にはインデックス付きのコレクションは使えません)。
次に双方向の多対多関連の例を示します。各カテゴリは多数のアイテムを持つことができ、各アイテムは多くのカテゴリに属することが出来ます。
<class name="Category">
<id name="id" column="CATEGORY_ID"/>
...
<bag name="items" table="CATEGORY_ITEM">
<key column="CATEGORY_ID"/>
<many-to-many class="Item" column="ITEM_ID"/>
</bag>
</class>
<class name="Item">
<id name="id" column="CATEGORY_ID"/>
...
<!-- inverse end -->
<bag name="categories" table="CATEGORY_ITEM" inverse="true">
<key column="ITEM_ID"/>
<many-to-many class="Category" column="CATEGORY_ID"/>
</bag>
</class>
関連の inverse 側にのみ行われた変更は永続化 されません。これは、 Hibernate は全ての双方向関連について、メモリ上に2つの表現を持っているという意味です。つまり一つは A から B へのリンクで、もう一つは B から A へのリンクということです。 Java のオブジェクトモデルについて考え、 Java で双方向関係をどうやって作るかを考えれば、これは理解しやすいです。下記に、 Java での双方向関連を示します。
category.getItems().add(item); // The category now "knows" about the relationship item.getCategories().add(category); // The item now "knows" about the relationship session.persist(item); // The relationship won't be saved! session.persist(category); // The relationship will be saved
関連の inverse ではない側は、メモリ上の表現をデータベースに保存するのに使われます。
双方向の一対多関連を定義するには、一対多関連を多対一関連と同じテーブルのカラムにマッピングし、多側に inverse="true" と宣言します。
<class name="Parent">
<id name="id" column="parent_id"/>
....
<set name="children" inverse="true">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child">
<id name="id" column="child_id"/>
....
<many-to-one name="parent"
class="Parent"
column="parent_id"
not-null="true"/>
</class>
関連の片側に inverse="true" を設定しても、カスケード操作に影響を与えません。これらは直交した概念です。