如何在Hibernate中使用级联和反向?有哪些定义它们的标签/过程?它们是否相互关联,以及它们如何有用?
在多对多关系中,通过中间表进行关联。 "级联" 表示记录是否会在子表中被创建/更新。而 "反向" 则表示记录是否会在中间表中被创建/更新。
例如,假设以下情况: 一个学生可以拥有多个电话。因此,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)
。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是关系的所有者,因此即使创建了新的学生,但中介表也不会被更新。
因此,在两个实体之间的关系中,“级联”影响另一个实体表,“反向”影响中介表。因此它们的影响是相互独立的。
引用自“级联”和“反向”的区别:
1. 反向:用于确定哪一侧是关系所有者,以管理关系(插入或更新外键列)。
2. 级联:在级联中,完成一个操作(保存、更新和删除)后,它将决定是否需要在与之相互关系的其他实体上调用其他操作(保存、更新和删除)。
结论:简而言之,“反向”决定哪一侧将更新外键,而“级联”决定接下来应该执行什么操作。两者在关系上看起来非常相似,但它们完全是两个不同的事情。Hibernate开发人员值得花时间研究它,因为误解概念或误用会在应用程序中带来严重的性能或数据完整性问题。
还可以查看这个论坛主题:https://forum.hibernate.org/viewtopic.php?f=1&t=949041
这些是正交的概念。
在关联中,必须使用 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
- 包括所有级联操作;