休眠-多次删除+插入操作而不调用冲洗方法会导致重复

时间:2018-11-14 13:18:18

标签: java hibernate spring-data-jpa

我有恋爱关系

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方法?

1 个答案:

答案 0 :(得分:0)

来自CrudRepository#save javadoc

  

S save(S实体)

     

保存给定的实体。 将返回的实例用于进一步的操作,因为保存操作可能已完全更改了实体实例。

所以我相信当您替换为:

时,您的问题将得到解决。
parent = parentRepository.save(parent);

在您的代码中,您将继续对未附加到上下文的实体进行操作,从而导致重复。