Hibernate中级联和反向的区别是什么,它们有什么用途?

47

如何在Hibernate中使用级联和反向?有哪些定义它们的标签/过程?它们是否相互关联,以及它们如何有用?


2
在谷歌上搜索“hibernate cascade inverse”作为第三个结果出现了这个 - Péter Török
哦,我没有注意到你已经在引用同一个链接了。 - YoK
1
我和@ArunKumar认为Kaushik Lele的答案应该被标记为被接受的答案。 - TechSpellBound
3个回答

90

在多对多关系中,通过中间表进行关联。 "级联" 表示记录是否会在子表中被创建/更新。而 "反向" 则表示记录是否会在中间表中被创建/更新。

例如,假设以下情况: 一个学生可以拥有多个电话。因此,Student类具有Phone集合属性。 另外,一个电话可以被多个学生拥有。因此,Phone类具有Students集合属性。 此映射在stud_phone表中提到。

因此,共有三个表,即Student、Phone和stud_phone(中介)表。 映射可能如下所示:

<set name="phoneset" table="stud_phone" cascade="save-update" inverse="true">
  <key column="mapping_stud_id">< /key>
  <many-to-many class="com.domain.Phone" column="mapping_phon_id"/>
</set> 
创建一个新的学生对象,并向其集合中添加了2个新的电话对象。然后调用session.save(student_obj)
根据“级联”和“反向”设置不同,将触发不同的查询。
以下是不同的级联和反向组合及其影响。
1)级联为NONE且反向为false
Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)

2) CASCADE是NONE且INVERSE为true。

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)

3) CASCADE 是保存更新,INVERSE 是 false。

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)

4)CASCADE是保存-更新,INVERSE为真

Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)

可以看出,只有在级联为“save-update”时,PHONE表中才会创建记录。否则不会。

当INVERSE为false(即Student是关系的所有者)时,会更新中介表STUD_PHONE。当inverse为true时,Phone是关系的所有者,因此即使创建了新的学生,但中介表也不会被更新。

因此,在两个实体之间的关系中,“级联”影响另一个实体表,“反向”影响中介表。因此它们的影响是相互独立的。


我有一个疑问:当inverse=false时,意味着Student是关系所有者,即Student是父级。因此,如果我们更新学生表,则Phone(子表)将自动更新。但是,当inverse=true时,Phone是关系所有者,即Phone是父级。那么,如果我们更新Phone表,学生表是否会得到更新?请解释这种情况。 - Sumit Kandoi
@SumitKandoi,正如答案中所解释的那样,它是由“级联”设置决定的。因此,“反向”设置并不重要。 - Kaushik Lele

27

引用自“级联”和“反向”的区别

1. 反向:用于确定哪一侧是关系所有者,以管理关系(插入或更新外键列)。

2. 级联:在级联中,完成一个操作(保存、更新和删除)后,它将决定是否需要在与之相互关系的其他实体上调用其他操作(保存、更新和删除)。

结论:简而言之,“反向”决定哪一侧将更新外键,而“级联”决定接下来应该执行什么操作。两者在关系上看起来非常相似,但它们完全是两个不同的事情。Hibernate开发人员值得花时间研究它,因为误解概念或误用会在应用程序中带来严重的性能或数据完整性问题。

还可以查看这个论坛主题:https://forum.hibernate.org/viewtopic.php?f=1&t=949041


7

这些是正交的概念。

在关联中,必须使用 inverse 属性或 mappedBy 属性(在 one-to-many/ many-to-one 关联中为多端,在 many-to-many 关联中为任意一端)将其中一个端标记为反向。这些信息是Hibernate正确确定 Java 类(面向对象关联)将如何映射到数据库表格(关系型关联)所需的。

那么级联呢?您可以明确指定 Hibernate 执行与相关实体的操作:

  • CascadeType.PERSIST - 当对拥有者调用 save()persist() 方法时,所有相关联的实体也会被保存;
  • CascadeType.REMOVE - 当对拥有者调用 delete() 方法时,所有相关联的实体也会被删除;
  • CascadeType.MERGE - 当对拥有者调用 merge() 方法时,所有相关联的实体也会被合并到受管/持久状态;
  • CascadeType.REFRESH - 当对拥有者调用 refresh() 方法时,所有相关联的实体也会从其数据库表示中进行刷新;
  • CascadeType.DETACH - 当与此实体相关联的会话关闭时,所有相关实体将处于分离状态;
  • CascadeType.ALL - 包括所有级联操作;
  • “孤儿删除” - 从关系中删除相关实体时,也会从数据库中删除关联实体。

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