何时在NHibernate/Hibernate-OneToMany关系上使用inverse=false?

何时在NHibernate/Hibernate-OneToMany关系上使用inverse=false?,nhibernate,hibernate,collections,one-to-many,inverse,Nhibernate,Hibernate,Collections,One To Many,Inverse,我一直在努力掌握Hibernate的反向属性,这似乎只是概念上困难的事情之一 我得到的要点是,当您有一个父实体(例如父实体)使用一对多映射拥有一个子对象集合时,在映射上设置inverse=true会告诉Hibernate“另一端(子实体)有责任更新自身以维护其表中的外键引用” 在代码中将子对象添加到集合中,然后保存父对象(设置了cascade all)时,这样做似乎有两个好处:(因为没有逆集合,Hibernate认为它有两个地方可以更新FK关系),根据官方文档: 如果 协会宣布成立 非空,NHi

我一直在努力掌握Hibernate的反向属性,这似乎只是概念上困难的事情之一

我得到的要点是,当您有一个父实体(例如父实体)使用一对多映射拥有一个子对象集合时,在映射上设置inverse=true会告诉Hibernate“另一端(子实体)有责任更新自身以维护其表中的外键引用”

在代码中将子对象添加到集合中,然后保存父对象(设置了cascade all)时,这样做似乎有两个好处:(因为没有逆集合,Hibernate认为它有两个地方可以更新FK关系),根据官方文档:

如果 协会宣布成立 非空,NHibernate可能导致 创建时违反约束 或更新关联。阻止 对于这个问题,您必须使用 双向关联 多值端(集合或包) 标记为reverse=“true”


到目前为止,这一切似乎都是有道理的。我不明白的是:你什么时候不想在一对多关系上使用inverse=true?

如果你想有一个单向关联,即孩子们不能导航到父母。如果是这样,FK列应该可以为空,因为子项将在父项之前保存。

正如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>

在这种情况下,您会将FK列设置为可空,因为保存sm的操作将插入SpyMaster表和Spy表,并且只有在这之后,才会更新Spy表以设置FK。在这种情况下,如果我们设置inverse=true,FK将永远不会得到更新。

尽管接受了高投票率的答案,我还有另一个答案

考虑具有以下关系的类图:

Parent => list of Items Item => Parent 父项=>项目列表 项=>父项 没有人说过,Item=>Parent关系与Parent=>Items关系是冗余的。项可以引用任何父项

但在应用程序中,您知道这些关系是冗余的。您知道,这些关系不需要单独存储在数据库中。因此,您决定将其存储在一个从项指向父项的单个外键中。这些最少的信息足以建立列表和引用

要将此映射到NH,您只需执行以下操作:

  • 对两个关系使用相同的外键
  • 告诉NH一个(列表)对另一个是冗余的,在存储对象时可以忽略。(这就是NH对
    inverse=“true”
    的实际作用)
这些是与反向相关的思想。没有别的了。这不是一种选择,只有一种正确映射的方法


间谍问题: 如果您希望支持从项目到父项的引用,则这是一个完全不同的讨论。这取决于您的业务模式,NH在这方面不做任何决定。如果其中一个关系缺失,那么当然没有冗余,也没有使用反向


误用:如果在内存中没有任何冗余的列表上使用reverse=“true”,它就不会被存储。如果您没有指定inverse=“true”如果它应该存在,NH可能会存储冗余信息两次。

这对我不起作用。它从不运行更新。我发现这个答案比公认的答案更容易理解,而且比我的答案简单得多。 Parent => list of Items Item => Parent