Hibernate - множественные операции удаления + вставки без вызова метода очистки приводят к дублированию - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть отношения:

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 голосов
/ 14 ноября 2018

С CrudRepository#save Javadoc :

S сохранить (S-объект)

Сохраняет данную сущность. Используйте возвращенный экземпляр для дальнейших операций , поскольку операция сохранения могла полностью изменить экземпляр объекта.

Так что я считаю, что ваша проблема будет решена, когда вы замените:

parent = parentRepository.save(parent);

В вашем коде вы продолжаете работу с сущностью, не связанной с контекстом, что приводит к дублированию.

...