在Hibernate中使用inverse true

10

我正在阅读Hibernate文档,并遇到了反向属性的概念。由于我是Hibernate的新手,所以我很难正确理解这个概念。

http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/collections.html#collections-bidirectional

<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="ITEM_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="true" 应用于 categories ,因此我理解 categories 是反向端。
但是我发现我的理解有一些矛盾:
引用块中说:

只对关联的反向端进行的更改不会被持久化。

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

如果categories在反向端,那么关系是如何保存的?
非反向端用于将内存表示保存到数据库中。
通过查看示例并阅读上述语句,我知道categories在非反向端。
请帮助我了解如何解释inverse="true"属性。在搜索网络并查看SO答案后,我知道了这个属性的有用性,但我仍然感到困惑。
2个回答

15
inverse="true"基本上意味着反向关系也在其他类的类定义中映射。但是,它真正的含义是定义这两个实体(父或子)中哪一方是关系所有者。因此,在Hibernate映射中,inverse="true" 表示此类(具有此XML定义的类)是关系所有者;而另一个类则是子类。
如果你想了解更多信息,那么我肯定会看看这篇文章:http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/,因为在Hibernate中,这个属性的含义很容易被误解。

2
我认为这篇文章非常令人困惑(尽管它是谷歌搜索“hibernate inverse”的第一个结果)。请看这条评论http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/#comment-1129060935 - Ido.Co

2

Inverse 关键字用于定义哪一侧是拥有者以维护关系的。根据此属性,更新和插入的过程会有所不同。

假设我们有两个表:

principal_tablemiddle_table

它们之间的关系是一对多。Hibernate 的映射类分别为 PrincipalMiddle

因此,Principal 类具有 Middle 对象的 SET。XML 映射文件应该如下所示:

<hibernate-mapping>
    <class name="path.to.class.Principal" table="principal_table" ...>
    ...
    <set name="middleObjects" table="middle_table" inverse="true" fetch="select">
        <key>
            <column name="PRINCIPAL_ID" not-null="true" />
        </key>
        <one-to-many class="path.to.class.Middel" />
    </set>
    ...

由于inverse被设置为“true”,这意味着“Middle”类是关系的所有者,因此主类将不会更新该关系。

因此,可以按照以下方式实现更新过程:

session.beginTransaction();

Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");


Middle middleObject = new Middle();
middleObject.setSomething("1");

middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);

session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually

session.getTransaction().commit();

更多信息可以在这里找到。这是一个关于如何使用inverse属性的详细教程,同时展示了Hibernate如何将其转换为SQL查询语句。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接