Hibernate - multiples delete + insert operations without calling flush method causes duplicates

Viewed 81

I have a relationship:

Parent {
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
    private List<Child> children= new ArrayList<>();
}

Child {
    @ManyToOne
    private Parent parent;
}

I want to remove all children and add new ones. That's why I call:

List<Child> newChildren = Arrays.asList(firstChild, secondChild);
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent); - I'm using spring data

However I saw that when I call the above code twice (I have more complicated logic, but this is the simplest case how I was able to reproduce my problem) without calling flush() method, Hibernate adds duplicate entries to the database (parent will have 4 children):

parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent);
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
parentRepository.save(parent);

Replacing savewith saveAndFlush fixes above code and causes that parent has only 2 children.

Why is it necessary to call flush method before deleting and inserting new children to the parent?

1 Answers

From CrudRepository#save javadoc:

S save(S entity)

Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.

So I believe your problem will be solved when you replace by:

parent = parentRepository.save(parent);

In your code, you continue operation on entity not attached to context, thus causing duplications.

Related