Hibernate: @OneToMany - @ManyToOne Entity удаляется, но снова появляется в коллекции - PullRequest
0 голосов
/ 24 августа 2018

У меня проблема, и я впадаю в отчаяние: я удаляю элемент из коллекции (List), Hibernate генерирует запросы и говорит, что удаляет элемент - но в конце он появляется снова. До рефакторинга все работало отлично. Теперь все работает как положено, только удаление элементов из этой коллекции вызывает у меня головную боль:

  • пружинный башмак 1.5.13

До рефакторинга:

У меня был список с заданиями (Task) в сущности Tour. Задача также поддерживала связь со своим туром. Итак: задача может иметь один тур, а тур может иметь несколько задач.

Мне удалось без проблем удалить задачи из тура: * Я установил тур на стороне задачи на ноль * убрал задачу из списка ==> отлично сработало

Внезапно - после рефакторинга - он перестал работать. Только удаление. Что я сделал: я изменил тип задачи на абстрагирование и создал подкласс «HandoverTask» (потому что я хочу больше задач другого типа) - @Inheritance (стратегии = InheritanceType.SINGLE_TABLE).

Мой общий код работает отлично, не работает только удаление задач из тура. В журналах Hibernate я вижу, что Hibernate удаляет задачу из списка, но на более позднем этапе она появляется снова (я пропустил ненужные атрибуты):

o.hibernate.internal.util.EntityPrinter  : Listing entities:
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.Tour{ [.....] tasks=[com.mhds.backend.domain.entities.task.Task#1001]}
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.task.HandoverTask{ [.....] tour=com.mhds.backend.domain.entities.Tour#951, [.....] }
[.....] left out select statement
o.h.e.i.AbstractFlushingEventListener    : Dirty checking collections
o.hibernate.engine.spi.CollectionEntry   : Collection dirty: [com.mhds.backend.domain.entities.Tour.tasks#951]
o.hibernate.engine.internal.Collections  : Collection found: [com.mhds.backend.domain.entities.Tour.tasks#951], was: [com.mhds.backend.domain.entities.Tour.tasks#951] (initialized)
o.h.e.i.AbstractFlushingEventListener    : Flushed: 0 insertions, 1 updates, 0 deletions to 2 objects
o.h.e.i.AbstractFlushingEventListener    : Flushed: 0 (re)creations, 1 updates, 0 removals to 1 collections2018-08-24 12:19:13.898 DEBUG 29430 --- [           main] o.hibernate.internal.util.EntityPrinter  : Listing entities:
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.Tour{ [.....] tasks=[]}
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.task.HandoverTask{ [.....] tour=null [.....]}
org.hibernate.SQL                        : update mhds_task set [.....] tour_id=?, [.....] where task_id=?
[.....] Left out unnecessary attributes
o.h.type.descriptor.sql.BasicBinder      : binding parameter [10] as [BIGINT] - [null]
[.....] Left out unnecessary attributes
o.h.e.i.AbstractFlushingEventListener    : Processing flush-time cascades

Первый: tasks = [com.mhds.backend.domain.entities.task.Task # 1001]

Позже: tasks = []

Вы можете видеть - задача находится в списке, а тур в задаче, после удаления список задач пуст, а тур пуст.

Позже в журналах я вижу, что список снова распространяется с записью задачи, а тур по сайту задачи все еще пуст:

o.hibernate.internal.util.EntityPrinter  : Listing entities:
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.Tour{ [.....] tasks=[com.mhds.backend.domain.entities.task.Task#1001]}
o.hibernate.internal.util.EntityPrinter  : com.mhds.backend.domain.entities.task.HandoverTask{ [.....] tour=null, [.....]}
org.hibernate.SQL                        : update mhds_task set tasks_list_index=? where task_id=?
o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [INTEGER] - [0]
o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [1001]
o.h.e.i.AbstractFlushingEventListener    : Processing flush-time cascades
o.h.e.i.AbstractFlushingEventListener    : Dirty checking collections

И задания вернулись:

задачи = [com.mhds.backend.domain.entities.task.Task # 1001]

Так что это приводит к сбою моих модульных тестов. Во время отладки я вижу, что записи удаляются из списка - но как только я вернусь в класс, который выполняет тесты JUnit - они вернулись. Я уже пробовал несколько «ручных» сбросов, но записи возвращаются в любое время. Я не могу найти никаких вставок между вышеупомянутыми утверждениями или откатами, они следуют друг за другом.

Задача:

@Entity
@EntityListeners(HandoverTaskEntityListener.class)
@Table(name = "mhds_task")
public class HandoverTask extends Task{

[...]

@ManyToOne
@JoinColumn(name = "tour_id", nullable = true)
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,    property="id")
@JsonIdentityReference(alwaysAsId=true)
@JsonProperty("tourId")
private Tour tour;

public Tour getTour() {
    if (this.tour != null)
        return tour;
    return null;
}

public void setTour(Tour tour) {
    this.tour = tour;
    if (tour == null) {
        this.state = TaskState.open;
    } else {
        this.state = TaskState.scheduled;
    }
}

[...]

}

Tour:

@Entity
@Table(name = "mhds_tour")
public class Tour extends AbstractAuditingEntity implements Serializable {

[...]

@OneToMany(fetch = FetchType.EAGER, mappedBy = "tour", cascade = {  CascadeType.PERSIST })
@OrderColumn(name = "tasks_list_index")
private List<HandoverTask> tasks;

public List<HandoverTask> getTasks() {
    return tasks;
}

public void removeTask(HandoverTask task) {
    this.tasks.remove(task);
    // bidirectional
    task.setTour(null);
}

[...]


}

Удаление происходит методом Tour.removeTask.

Любая помощь / идеи приветствуются! Я уже наткнулся на некоторые проблемы равенства, проблемы с хеш-кодом, но функция равенства реализована, и я не могу связать эти проблемы с моей конкретной.

С уважением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...