Jam*_*len 70 collections nhibernate hibernate inverse one-to-many
我一直试图掌握Hibernate的逆属性,它似乎只是概念上难以解决的问题之一.
我得到的要点是,当你有一个使用一对多映射的Child对象集合的父实体(例如Parent)时,在映射上设置inverse = true告诉Hibernate'另一边(Child) )有责任更新自己以维护其表中的外键引用'.
这样做对于在代码中向集合中添加Children,然后保存Parent(使用cascade-all set)有两个好处:在数据库上保存一个不必要的命中(因为没有逆集,Hibernate认为它有两个地方更新FK关系),并根据官方文档:
如果关联的列被声明为NOT NULL,则NHibernate在创建或更新关联时可能会导致约束违规.要防止出现此问题,必须使用标记为inverse ="true"的多值结束(集合或包)的双向关联.
到目前为止,这一切似乎都有意义.我不明白是这样的:你什么时候会不希望使用逆=真正在一个一对多的关系?
Nig*_*gel 82
正如Matthieu所说,唯一一个你不想设置inverse = true的情况是,孩子负责自我更新是没有意义的,例如在孩子不知道其父母的情况下.
让我们尝试一个现实世界,而不是任何人为的例子:
<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>
Run Code Online (Sandbox Code Playgroud)
间谍可以有间谍,但间谍从来不知道他们的间谍是谁,因为我们没有在间谍班中包含多对一的关系.另外(方便地)间谍可能会变成流氓,所以不需要与间谍大师联系.我们可以创建如下实体:
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);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以将FK列设置为可为空,因为保存sm的行为将插入到SpyMaster表和Spy表中,然后才会更新Spy表以设置FK.在这种情况下,如果我们设置inverse = true,则FK永远不会更新.
Ste*_*ger 29
尽管有高投票的答案,我还有另一个答案.
考虑具有这些关系的类图:
Parent => list of Items Item => Parent
没有人说过,Item => Parent关系对于Parent => Items关系是多余的.物品可以引用任何父母.
但是在你的应用程序中,你知道关系是多余的.您知道这些关系不需要单独存储在数据库中.因此,您决定将其存储在单个外键中,从Item指向Parent.这个最小的信息足以构建列表和引用.
您需要做的就是用NH来映射它:
inverse="true")这些是与逆相关的思想.没有其他的.它不是一种选择,只有一种正确的映射方式.
间谍问题:如果你想支持从Item到Parent的引用,这是一个完全不同的讨论.这取决于您的商业模式,NH不会在此做出任何决定.如果缺少其中一个关系,那么当然没有冗余并且没有使用逆.
误用:如果在内存中没有任何冗余的列表中使用inverse ="true",则它不会被存储.如果你没有指定inverse ="true",那么NH可以存储两次冗余信息.
| 归档时间: |
|
| 查看次数: |
25962 次 |
| 最近记录: |