由于 重复性的操作十分烦琐,尤其是在处理多个彼此关联对象情况下,此时我们可以使用级联(Cascade)操作。级联 在关联映射中是个重要的概念,指当主动方对象执行操作时,被关联对象(被动方)是否同步执行同一操作。

在实际的项目中,经常可以使用到级联的操作。本周也在级联上遇到了问题。

级联类型

jpa的级联类型(Cascade Types)包括:

ALL

PERSIST

MERGE

REMOVE

REFRESH

DETACH

ALL类型包括所有的jpa级联类型和Hibernate的级联类型。具体的使用方法,就是在实体的关联注解上使用级联类型:

@Entity

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

Long id;

String name;

@OneToMany(cascade = CascadeType.ALL)

List courseList = new ArrayList<>();

.......

}

@Entity

public class Course {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

Long id;

String name;

.....

}

PERSIST

PERSIST操作会将对象持久化,当使用CascadeType.PERSIST时,代表持久化父对象时,子对象也相应的持久化,也就是级联保存。

Student student = new Student("s1");

student.setCourseList(Arrays.asList(new Course("c1")));

studentRepository.save(student);

对应的sql语句为:

insert into student (name) values (?)

insert into course (name) values (?)

insert into student_course_list (student_id, course_list_id) values (?, ?)

MERGE

MERGE操作会将具有相同标识符的对象进行更新,当时用CascadeType.MERGE时,代表当父对象更新里的子对象更新时,更新操作会传递到子对象。

Student student = new Student("s1");

student.setCourseList(Arrays.asList(new Course("c1")));

studentRepository.save(student);

student.setName("s2");

student.getCourseList().get(0).setName("c2");

studentRepository.save(student);

对应➋处的sql语句为:

select student0_.id as id1_1_1_, student0_.name as name2_1_1_, courselist1_.student_id as student_1_2_3_, course2_.id as course_l2_2_3_, course2_.id as id1_0_0_, course2_.name as name2_0_0_ from student student0_ left outer join student_course_list courselist1_ on student0_.id=courselist1_.student_id left outer join course course2_ on courselist1_.course_list_id=course2_.id where student0_.id=1

update course set name=c2 where id=1

update student set name=s2 where id=1

具体流程为:

从学生表中查找学生并连接课程表

更新课程中改变的属性,更新学生中改变的属性

REMOVE

REMOVE操作会删除数据库的实体,使用CascadeType.REMOVE时,会级联删除所有子对象。

Student student = new Student("s1");

student.setCourseList(Arrays.asList(new Course("c1"), new Course("c2")));

studentRepository.save(student);

studentRepository.delete(student);

➋处对应的sql语句为:

delete from student_course_list where student_id=1

delete from course where id=1

delete from course where id=2

delete from student where id=1

REFRESH

REFRESH操作代表重新从数据库中获取实体信息,使用了CascadeType.REFRESH后,会级联的获取子对象在数据库的信息。

Student student = new Student("s1");

student.setCourseList(Arrays.asList(new Course("c1"), new Course("c2")));

studentRepository.save(student);

entityManager.refresh(student);

DETACH

DETACH操作表示从持久化的上下文移除对象,当使用了CascadeType.DETACH后,子对象也会从持久化的上下文中移除。

Student student = new Student("s1");

Course course = new Course("c1");

student.setCourseList(Arrays.asList(course));

studentRepository.save(student);

assertThat(entityManager.contains(student)).isTrue();

assertThat(entityManager.contains(course)).isTrue();

entityManager.detach(student);

assertThat(entityManager.contains(student)).isFalse();

assertThat(entityManager.contains(course)).isFalse();

orphanRemoval

之前的级联代表的都是从父操作到子操作的延伸,在写项目的时候,就遇到了这样的问题:学生选择了政治、英语课,然后修改学生课程为语文、数学。然而级联并不能做到当学生课程集合改变时,自动删除原先课程并创建新课程。这时候就需orphanRemoval了,官方文档给出的解释为:

When a target entity in one-to-one or one-to-many relationship is removed from the relationship, it is often desirable to cascade the remove operation to the target entity. Such target entities are considered “orphans,” and theorphanRemovalattribute can be used to specify that orphaned entities should be removed. For example, if an order has many line items and one of them is removed from the order, the removed line item is considered an orphan. IforphanRemovalis set totrue, the line item entity will be deleted when the line item is removed from the order.

TheorphanRemovalattribute in@OneToManyand@oneToOnetakes a Boolean value and is by default false.

The following example will cascade the remove operation to the orphaned customer entity when it is removed from the relationship:

@OneToMany(mappedBy="customer", orphanRemoval="true")

public List getOrders() { ... }

大致就是说,当一个one-to-one或一个one-to-many的关系发生改变的时候,他会自动删除相关联的数据。

Student student = new Student("s1");

List courses1 = new ArrayList<>();

courses1.add(new Course("c1"));

student.setCourseList(courses1);

studentRepository.save(student);

student.getCourseList().clear();

student.getCourseList().add(new Course("c2"));

studentRepository.save(student);

对应的sql语句为:

insert into course (name) values (?)

insert into student_course_list (student_id, course_list_id) values (?, ?)

delete from course where id=?

注意当子实体与其他实体还有关联时,删除操作会失败。所以orphanRemoval只适用与子实体仅与父实体有关联。

jpa级联添加_jpa级联(Cascade)操作相关推荐

  1. java 级联删除_JPA级联删除

    本篇文章帮大家学习JPA级联删除,包含了JPA级联删除使用方法.操作技巧.实例演示和注意事项,有一定的学习价值,大家可以用来参考. 级联移除用于指定如果父实体被移除,则其所有相关实体也将被移除. 以下 ...

  2. jpa级联添加_JPA中的一对多双向关联与级联操作

    学习Spring有两周时间了 , 个人觉得服务端主要实现的是数据关系的维护和数据结构的制定 , 以及由业务需求产生的CRUD , 只要保证对前端提供的接口稳定高效响应 , 具体的前端实现完全不关心. ...

  3. 数据库级联操作mysql_Oracle数据库中的级联查询、级联删除、级联更新操作教程...

    级联查询在ORACLE 数据库中有一种方法可以实现级联查询 select * //要查询的字段 from table //具有子接点ID与父接点ID的表 start with selfid=id // ...

  4. [NHibernate]一对多关系(级联删除,级联添加)

    目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...

  5. Oracle数据库中的级联查询、级联删除、级联更新操作教程

    这里整理了Oracle中的三种级联操作,其中Oracle定义外健的时候可以定义级联删除,但是没有级联修改的语法,当然可以用触发器实现,下面我们详细来看Oracle数据库中的级联查询.级联删除.级联更新 ...

  6. oracle+cascade=gt;true,mysql数据库主外键级联删除脚本RESTRICT -- CASCADE

    在项目中,我们一般在数据库设计的时候做主外键关联设计,要么就不做.但是这样不符合规范,呵呵. 建立主外键关系的时候,默认是不能级联删除的.而出现往往在删除主表的数据时报错, 需要先删除从表然后再删除主 ...

  7. Oracle之外键(Foreign Key)使用方法具体解释(二)- 级联删除(DELETE CASCADE)

    Oracle外键(Foreign Key)之级联删除(DELETE CASCADE) 目标 演示样例解说怎样在Oracle外键中使用级联删除 什么是级联删除(DELETE CASCADE)? 级联删除 ...

  8. mysql数据库教程级联_Mysql实现级联操作(级联更新、级联删除)

    tablestu( sidint UNSIGNED primary keyauto_increment, namevarchar(20) not null) TYPE=InnoDB charset=u ...

  9. mysql级联更新_Mysql实现级联操作(级联更新、级联删除)(转)

    一.首先创建两张表stu,sc create table stu( sid int UNSIGNED primary key auto_increment, name varchar(20) not ...

最新文章

  1. yum源简单介绍及本地yum源的搭建
  2. 微信后端服务架构及其过载控制系统DAGOR
  3. 网页制作中的背景处理
  4. Redis中bitmap的妙用 1
  5. 在线机房改造类项目建设难点的研究
  6. 【转贴】大型ORACLE数据库优化设计方案
  7. Qt / 伪状态和子部件
  8. Swift语言快速入门
  9. 分享一款最近比较火爆的宝石迷情游戏游戏源码安卓版
  10. JSON (一) JSON语法和数据类型
  11. java 8 lambda reduce_java8种的reduce方法和lambda表达式结合使用
  12. 大学英语计算机开学考试试题,2018年全国大学英语四级考试阅读理解试题:学习计算机...
  13. 主链增幅最高飚至 152%,主流币却惊现回落;以太坊发币速度持续放缓
  14. 九、索引与执行计划、索引的分类
  15. 使用js实现百度地图与高德地图经纬度的转换
  16. BT种子 kitty
  17. 泰灏咨询的使命及愿景
  18. cesium中的飞行动画fly
  19. 笔记本重装windows系统,office全家桶消失的解决方案
  20. 小米云服务器怎么管理员密码,小米路由器管理密码怎么设置 小米路由器管理密码设置介绍【图文】...

热门文章

  1. hook微信 python_GitHub - zkqiang/wechathook: 借助微信hook,拦截修改某些call,填充进我们的Python代码,进行微信公众号文章的爬取...
  2. 访问控制列表之基本ACL、高级ACL 、 高级ACL之ICMP、高级ACL之telnet
  3. HTML5小游戏之爱心鱼
  4. Artificial Neural Networks FileStorage of OpenCV
  5. Rviz 实现 pannel 插件
  6. JAVA生成高强度密码(包含随机数字+随机英文大小写)
  7. android https HttpsURLConnection 忽略证书
  8. 又开始的python-day10-20200821-文件操作相关内置函数-拷贝-读取-写入
  9. spring boot 1.x和 2.x通过代码修改默认address和端口
  10. ctfshow_萌新_萌新隐藏题