Hibernate反向属性

7

我正在创建一个一对多的关系,因此我有一个父级和一个子级。级联属性被设置为all。

我想知道,如果我们考虑以下代码片段:

Parent p = (Parent) session.load(Parent.class, pid); 
Child c = new Child("child element");
p.addChild(c);
session.flush();
  • Q1) 如果父对象拥有关系,例如,对于父对象inverse=false,则子元素的添加是否会更新数据库?
  • Q2) 如果子对象拥有关系,例如,对于父对象inverse=true,则子元素的添加是否会更新数据库?
  • Q3) 在上述代码中,谁拥有关系对于更新是否可见没有影响吗?

非常感谢。

4个回答

5
Case inverse = false: 在这种情况下,父亲要负责保存-更新孩子及其关系。因此,在您的示例中,孩子将在数据库中更新。将会有两个SQL查询:1)插入孩子。2)使用父ID的外键更新孩子。 Case Inverse = true: 在这种情况下,孩子要负责自己保存-更新。因此,在您的代码中,孩子将保存在数据库中,但父亲的外键将为空。只会执行一个SQL查询,即插入孩子。要更新父亲的外键,您需要手动保存孩子。
Child child = new Child();
child.setParent(parent);
session.save(child);

我认为,这些案例的答案解释了你第三个问题的答案。
希望能对你有所帮助。

2
不完全正确。级联与反向无关。正如你所说,父-FK 将为 null,但你只需要将关系设置到父级,不需要进行 保存 - Stefan Steinegger
@Stefan:感谢您的建议!所以,在我的代码中,如果孩子负责关系,那么当我执行p.addChild(child)时,孩子将被保存在数据库中,但外键将为空。然后我需要编写语句:child.setParent(parent)来设置外键。这样对吗? - TimeToCodeTheRoad
不需要添加session.save(child),因为级联已经处理了。 - TimeToCodeTheRoad
这是正确的吗?我的意思是不需要添加sessin.save(child)。 - TimeToCodeTheRoad
@Stefan,你说得很对。不需要单独保存子项。但是,如果父项有子项列表(而不是集合),则在子表中会有一个索引列来跟踪子项索引。如果inverse=true并且我们不单独保存子项,则该列将在子表中保持为空。因此,下次从父项获取子项列表时,它将抛出异常,指示集合的空索引列。在这种情况下,我是正确的吗? - Nikunj
显示剩余2条评论

3

“Inverse”只是告诉NH,外键被映射了两次,通常是一对多和多对一,因此只需要从一侧存储。

问题1:子项通过级联存储,但父项-FK为空。(除非在p.addChild(c)中设置了子项的父项关系。)

问题2:与问题1相同。

问题3:完全正确。


1
如果我们使用inverse=true,意味着子对象负责更新关系。强制要求子对象包含父对象,否则外键不会被更新。

0
在两个不同实体之间的父子关系中,
例如一对多(1:N)或多对一(N:1)
父<- >子。 (所有者)(反向)
如果父是所有者,则子是其反向。
始终检查子项时使用反向。
默认情况下,我们始终从父方考虑。因此,默认情况下inverse = false表示父为所有者。
如果inverse = true,则子项是所有者。因此,实体的持久化始终从所有者方进行。

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