У меня проблема, и я впадаю в отчаяние: я удаляю элемент из коллекции (List), Hibernate генерирует запросы и говорит, что удаляет элемент - но в конце он появляется снова. До рефакторинга все работало отлично. Теперь все работает как положено, только удаление элементов из этой коллекции вызывает у меня головную боль:
До рефакторинга:
У меня был список с заданиями (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.
Любая помощь / идеи приветствуются! Я уже наткнулся на некоторые проблемы равенства, проблемы с хеш-кодом, но функция равенства реализована, и я не могу связать эти проблемы с моей конкретной.
С уважением