2

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?

buræquete
  • 14,226
  • 4
  • 44
  • 89
Toma
  • 380
  • 3
  • 17
  • Maybe this can give you an hint: https://stackoverflow.com/questions/21203875/difference-between-save-and-saveandflush-in-spring-data-jpa#21204085 – Tu.Ma. Nov 14 '18 at 13:27

1 Answers1

0

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.

Community
  • 1
  • 1
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67