我一直在试图让Hibernate的逆属性交手,这似乎只是那些东西,在概念上困难的一年。
我得到的要点是,当你有一个父实体(如母公司),其具有用一个一对多的映射子对象的集合,设置逆=上映射真实的告诉Hibernate认为,”对方(儿童)有责任进行自我更新,以保持其表”的外键引用。
这样做似乎有2个好处,当谈到在你的代码中加入儿童收集,然后保存父(与级联所有设置): 您保存不必要的命中数据库 (因为没有逆集,休眠认为它有两个地方更新FK关系),并根据官方的文档:
如果一个协会的列声明NOT NULL,NHibernate的可能导致违反约束时,它会创建或更新关联。 为了避免这个问题,你必须使用双向关联,用标记为逆=“真”的许多有价值的一端(套或袋)。
这一切都似乎是有道理至今。 我不明白这是:如果你不希望使用逆=真正在一个一对多的关系?
由于马修说,你不会想设置逆的唯一情况=真正的是它没有意义的,为孩子负责更新自身,比如在孩子有没有其父知情的情况下。
让我们试着一个真实的世界,而不是在所有人为的例子:
<class name="SpyMaster" table="SpyMaster" lazy="true">
<id name="Id">
<generator class="identity"/>
</id>
<property name="Name"/>
<set name="Spies" table="Spy" cascade="save-update">
<key column="SpyMasterId"/>
<one-to-many class="Spy"/>
</set>
</class>
<class name="Spy" table="Spy" lazy="true">
<id name="Id">
<generator class="identity"/>
</id>
<property name="Name"/>
</class>
间谍首脑可以有间谍,但间谍从来不知道自己的王牌间谍是谁,因为我们还没有列入间谍类多到一的关系。 同时,(方便)间谍可能会变成流氓,因此并不需要与是间谍有关。 我们可以按如下方式创建实体:
var sm = new SpyMaster
{
Name = "Head of Operation Treadstone"
};
sm.Spies.Add(new Spy
{
Name = "Bourne",
//SpyMaster = sm // Can't do this
});
session.Save(sm);
在这种情况下,你将设置FK列是空,因为节省了SM的行为会插入王牌间谍表和间谍表,只有经过它将然后更新间谍表设置FK。 在这种情况下,如果我们设置逆= true,则FK永远不会被更新。
尽管高投票接受的答案,我有另一种答案。
考虑这些关系的类图:
Parent => list of Items
Item => Parent
从来没有人说,该项目=>父关系是多余的父=>产品的关系。 一个项目可以引用任何父母。
但是,在你的应用程序, 你知道的关系是多余的 。 你知道,关系并不需要在数据库中分别存储。 所以你决定将其存储在一个单一的外键 ,从项目到父指点。 这个最小的信息足以建立清单和参考回来。
所有你需要做的这个映射与NH是:
- 使用这两种关系相同的外键
- 告诉NH之一(列表)是冗余的其他和存储对象时可以忽略不计。 (这就是NH实际上不
inverse="true"
)
这些是相关的逆思想。 没有其他的。 这是不是一种选择,只有一个正确的映射方式。
间谍的问题 :它是一个完全不同的讨论,如果你想支持从项目到家长参考。 这是到你的商业模式,NH不参加这个任何决定。 如果关系之一是缺少,当然还有没有冗余,没有用逆。
误用:如果您不具有在内存中的任何冗余的列表上使用逆=“真”,它只是没有得到保存。 如果不指定逆=“真”,如果它应该有,NH可以两次存储冗余信息。
如果你想有一个单向关联,即孩子们不能定位到父。 如果是这样,你FK列应为空,因为孩子会在父母面前被保存。
文章来源: When to use inverse=false on NHibernate / Hibernate OneToMany relationships?