6.3.2. 双向关联(Bidirectional associations)

双向关联允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联:

一对多(one-to-many)

Set或者bag值在一端, 单独值(非集合)在另外一端

多对多(many-to-many)

两端都是set或bag值

要建立一个双向的多对多关联,只需要映射两个many-to-many关联到同一个数据库表中,并再定义其中的一端为inverse(使用哪一端要根据你的选择,但它不能是一个索引集合)。

这里有一个many-to-many的双向关联的例子;每一个category都可以有很多items,每一个items可以属于很多categories:

  1. <class name="Category">
  2. <id name="id" column="CATEGORY_ID"/>
  3. ...
  4. <bag name="items" table="CATEGORY_ITEM">
  5. <key column="CATEGORY_ID"/>
  6. <many-to-many class="Item" column="ITEM_ID"/>
  7. </bag>
  8. </class>
  9. <class name="Item">
  10. <id name="id" column="CATEGORY_ID"/>
  11. ...
  12. <!-- inverse end -->
  13. <bag name="categories" table="CATEGORY_ITEM" inverse="true">
  14. <key column="ITEM_ID"/>
  15. <many-to-many class="Category" column="CATEGORY_ID"/>
  16. </bag>
  17. </class>

如果只对关联的反向端进行了改变,这个改变不会被持久化。 这表示Hibernate为每个双向关联在内存中存在两次表现,一个从A连接到B,另一个从B连接到A。如果你回想一下Java对象模型,我们是如何在Java中创建多对多关系的,这可以让你更容易理解:

  1. category.getItems().add(item); // The category now "knows" about the relationship
  2. item.getCategories().add(category); // The item now "knows" about the relationship
  3. session.persist(item); // The relationship won''t be saved!
  4. session.persist(category); // The relationship will be saved

非反向端用于把内存中的表示保存到数据库中。

要建立一个一对多的双向关联,你可以通过把一个一对多关联,作为一个多对一关联映射到到同一张表的字段上,并且在"多"的那一端定义inverse="true"

  1. <class name="Parent">
  2. <id name="id" column="parent_id"/>
  3. ....
  4. <set name="children" inverse="true">
  5. <key column="parent_id"/>
  6. <one-to-many class="Child"/>
  7. </set>
  8. </class>
  9. <class name="Child">
  10. <id name="id" column="child_id"/>
  11. ....
  12. <many-to-one name="parent"
  13. class="Parent"
  14. column="parent_id"
  15. not-null="true"/>
  16. </class>

在“一”这一端定义inverse="true"不会影响级联操作,二者是正交的概念!