文章目录
测试环境
Person类下有多个Car。
一无多无
新建一个Person并添加两个Cat到Person下。保存Person。
@GetMapping("/demo1")
public String demo1() {
Person person = new Person();
person.setName("demo1");
Cat cat1 = new Cat();
Cat cat2 = new Cat();
cat1.setName("cat1");
cat2.setName("cat2");
List<Cat> cats = new ArrayList<>();
cats.add(cat1);
cats.add(cat2);
person.setCats(cats);
// save是提交事务,对照缓存区跟快照区,不相同则提交
personRepository.save(person);
return "1- *-";
}
无级联报错
SQL语句直接插入和更新。
object references an unsaved transient instance - save the transient instance before flushing: com.example.demo.core.model.Cat
添加级联PERSIST
再次请求成功;SQL语句先都插入,再更新关系
一有多无
库中存在的Person添加两个new Cat。
@GetMapping("/demo2")
public String demo2() {
Person person = personRepository.findById(2L).orElse(null);
Cat cat1 = new Cat();
cat1.setName("cat21");
Cat cat2 = new Cat();
cat2.setName("cat22");
List<Cat> cats = new ArrayList<>();
cats.add(cat1);
cats.add(cat2);
person.setCats(cats);
personRepository.save(person);
// 没有merge会报错 指A类变化,会级联B对象(新增或者变化)
// 若有persist 没有merge会保存两个空对象进去
return "1+ *-";
}
无级联报错
SQL语句直接更新。
添加级联MERGE
SQL语句先将new的对象保存,然后再讲之前的关系删除(因为是OneToMany关联)。然后再更新关联。
添加级联PERSIST
PERSIST级联关系也能将Cat保存进库,但是值都为null。
一无多有
@GetMapping("/demo3")
public String demo3() {
Cat cat1 = catRepository.findById(3L).orElse(null);
cat1.setName("cat31");
Cat cat2 = catRepository.findById(4L).orElse(null);
cat2.setName("cat32");
List<Cat> cats = new ArrayList<>();
cats.add(cat1);
cats.add(cat2);
Person person = new Person();
person.setName("demo3");
person.setCats(cats);
personRepository.save(person);
return "1- *+";
}
成功
Person是关系的维护方。维护方不存在时,被维护方存在,保存维护方时会自动更新关系。
CascadeType.REFRESH
获取Person的信息时,保证获取Person.Cat的信息也是最新的。应用demo未找到。
CascadeType.REMOVE
删除Person实体时会删除Person关联的Cat。
无REMOVE级联删除时SQL为:
有REMOVE级联删除时SQL为:
orphanRemoval属性
@GetMapping("/orphanRemoval/{id}")
public String orphanRemoval(@PathVariable Long id) {
Person person = personRepository.findById(id).orElse(null);
person.getCats().remove(1);
return "orphanRemoval";
}
默认为false。表示移除关系时,将Cat的person_id设置为null,不删除实体。
如果设置为true。表示移除关系时,会将移除的Cat删除。
注意:当使用了orphanRemoval=true时,对setCats(List cats)方法时,需要先将之前的cats.clear(),不然会抛出未跟踪的对象引用集合异常。
如下:
public void setCats(List<Cat> cats) {
if (this.cats == null) {
this.cats = new ArrayList<>();
}
this.cats.clear();
this.cats.addAll(cats);
}