我有恋爱关系
Parent {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
private List<Child> children= new ArrayList<>();
}
Child {
@ManyToOne
private Parent parent;
}
我想删除所有孩子并添加新孩子。这就是为什么我打电话给我:
List<Child> newChildren = Arrays.asList(firstChild, secondChild);
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent); - I'm using spring data
但是我看到当我两次调用上面的代码(我有更复杂的逻辑,但是这是我能够重现问题的最简单的情况)而没有调用flush()
方法时,Hibernate将重复的条目添加到数据库(父级将有4个子级):
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent);
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent);
用save
替换saveAndFlush
可以解决上述代码,并导致其父节点只有2个孩子。
为什么在删除新的子代并将其插入父代之前需要调用flush方法?
答案 0 :(得分:0)
来自CrudRepository#save
javadoc:
S save(S实体)
保存给定的实体。 将返回的实例用于进一步的操作,因为保存操作可能已完全更改了实体实例。
所以我相信当您替换为:
时,您的问题将得到解决。parent = parentRepository.save(parent);
在您的代码中,您将继续对未附加到上下文的实体进行操作,从而导致重复。