Spring Boot-在save()方法上删除了关系



我的问题是:Project和Employee这两个表之间存在多对多关系。有一个更新给定员工的选项,但有一个小问题。更新员工后,hibernate会自动从连接的project_eemployee表中删除该员工的记录。

Hibernate:更新员工设置电子邮件=?,first_name=?,last_name=?employee_id=在哪里?

这发生在之后

Hibernate:从项目employee_id=中删除?

我正在学习一门课程,刚刚注意到这个错误。讲师的源代码在这里:

https://github.com/imtiazahmad007/spring-framework-course

我已经检查了你的github页面:

@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST},
fetch = FetchType.LAZY)
@JoinTable(name="project_employee",
joinColumns=@JoinColumn(name="employee_id"),
inverseJoinColumns= @JoinColumn(name="project_id")
)
@JsonIgnore
private List<Project> projects;

级联类型。合并+级联类型。PERSIST的意思是,如果保存了Employee实体,则必须保存Project实体引用。

在许多情况下,这意味着:

  • 通过外键删除
  • 批量插入

如果没有大容量插入,则说明持久性上下文存在问题(您正在保存一个具有空项目集合的实体(。

可能的解决方案:

  • 删除级联类型。合并+级联类型。如果您不想每次保存Employee时都更改项目,请坚持。您仍然可以通过存储库保存收集
  • 确保在保存操作时附加了集合。这将导致Delete+Insert,但结果会正常
  • 使用EmbeddedId将多对多更改为一对多

请参阅文档:

当实体从@ManyToMany集合中删除时,Hibernate只需删除链接表中的连接记录。不幸的是,此操作需要删除与给定父级关联的所有条目,并重新创建当前运行的持久上下文中列出的条目。

https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#associations-多对多

***从下面的对话框更新以使级联清晰。

比方说,你有两个实体A&B(省略getter和setter(。+回购

@Entity
@Table(name = "a")
public class A {
@Id
private Integer id;
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="a_b",
joinColumns=@JoinColumn(name="a_id"),
inverseJoinColumns= @JoinColumn(name="b_id")
)
private List<B> bs;

}
@Entity
@Table(name = "b")
public class B {
@Id
private Integer id;
private String name;

}

您的样本测试如下:

@Test
public void testSave() {
B b = new B();
b.setId(1);
b.setName("b");
b = bRepository.save(b);
A a = new A();
a.setId(1);
a.setName("a");
a.setBs(Collections.singletonList(b));
aRepository.save(a);
a.setName("new");
service.save(a); //watch sevice implementations below
}

版本1:

@Transactional
public void save(A a) {
aRepository.save(a);
}

休眠日志如下:

Hibernate: 
update
a 
set
name=? 
where
id=?
Hibernate: 
delete 
from
a_b 
where
a_id=?
Hibernate:
insert 
into
a_b
(a_id, b_id) 
values
(?, ?)

删除+大容量插入存在(尽管事实上,B-s实际上没有改变(

版本2:

@Transactional
public void save(A a) {
Optional<A> existing = aRepository.findById(a.getId());
if (existing.isPresent()) {
a.setBs(existing.get().getBs());
}
aRepository.save(a);
}

日志:

update
a 
set
name=? 
where
id=?

在这里,b-collection被强制重新附加,所以hibernate明白,它不需要级联。

最新更新