当使用逆=假NHibernate的/ Hibernate的一对多的关系?当使用逆=假NHiberna

2019-05-14 04:16发布

我一直在试图让Hibernate的逆属性交手,这似乎只是那些东西,在概念上困难的一年。

我得到的要点是,当你有一个父实体(如母公司),其具有用一个一对多的映射子对象的集合,设置逆=上映射真实的告诉Hibernate认为,”对方(儿童)有责任进行自我更新,以保持其表”的外键引用。

这样做似乎有2个好处,当谈到在你的代码中加入儿童收集,然后保存父(与级联所有设置): 您保存不必要的命中数据库 (因为没有逆集,休眠认为它有两个地方更新FK关系),并根据官方的文档:

如果一个协会的列声明NOT NULL,NHibernate的可能导致违反约束时,它会创建或更新关联。 为了避免这个问题,你必须使用双向关联,用标记为逆=“真”的许多有价值的一端(套或袋)。

这一切都似乎是有道理至今。 我不明白这是:如果你希望使用逆=真正在一个一对多的关系?

Answer 1:

由于马修说,你不会想设置逆的唯一情况=真正的是它没有意义的,为孩子负责更新自身,比如在孩子有没有其父知情的情况下。

让我们试着一个真实的世界,而不是在所有人为的例子:

<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永远不会被更新。



Answer 2:

尽管高投票接受的答案,我有另一种答案。

考虑这些关系的类图:

Parent => list of Items
Item => Parent

从来没有说,该项目=>父关系是多余的父=>产品的关系。 一个项目可以引用任何父母。

但是,在你的应用程序, 你知道的关系是多余的 。 你知道,关系并不需要在数据库中分别存储。 所以你决定将其存储在一个单一的外键 ,从项目到父指点。 这个最小的信息足以建立清单参考回来。

所有你需要做的这个映射与NH是:

  • 使用这两种关系相同的外键
  • 告诉NH之一(列表)是冗余的其他和存储对象时可以忽略不计。 (这就是NH实际上不inverse="true"

这些是相关的逆思想。 没有其他的。 这是不是一种选择,只有一个正确的映射方式。


间谍的问题 :它是一个完全不同的讨论,如果你想支持从项目到家长参考。 这是到你的商业模式,NH不参加这个任何决定。 如果关系之一是缺少,当然还有没有冗余,没有用逆。

误用:如果您不具有在内存中的任何冗余的列表上使用逆=“真”,它只是没有得到保存。 如果不指定逆=“真”,如果它应该有,NH可以两次存储冗余信息。



Answer 3:

如果你想有一个单向关联,即孩子们不能定位到父。 如果是这样,你FK列应为空,因为孩子会在父母面前被保存。



文章来源: When to use inverse=false on NHibernate / Hibernate OneToMany relationships?