我遇到了一个问题,我变得绝望:我从集合(列表)中删除一个项目,Hibernate生成查询并说,它删除了该项目-但最后,它再次出现。重构之前,一切工作正常。现在,一切都按预期进行,只有从此一个收藏夹中移除物品才让我头疼:
重构之前:
我在实体Tour中有一个包含任务(任务)的列表。该任务也与其巡回演出保持联系。因此:一个任务可以有一个环游,一个环游可以有多个任务。
我能够从游览中删除任务,而没有任何问题: *我将任务侧的游览设置为null *从列表中删除任务 ==>效果很好
在重构之后突然停止了工作。只有清除。我该怎么做:我将Task的类型更改为抽象,并创建了一个“ HandoverTask”子类(因为我想要更多不同类型的任务)-@Inheritance(strategy = 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
任务又回来了:
tasks = [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;
}
}
[...]
}
游览:
@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方法进行。
任何帮助/想法都感激!我已经偶然发现了一些等于,哈希码的问题-但是实现了等于,我无法将这些问题与具体问题联系起来。
最诚挚的问候