休眠状态:@OneToMany-@ManyToOne实体已删除,但再次出现在集合中

时间:2018-08-24 11:20:50

标签: java hibernate spring-boot one-to-many many-to-one

我遇到了一个问题,我变得绝望:我从集合(列表)中删除一个项目,Hibernate生成查询并说,它删除了该项目-但最后,它再次出现。重构之前,一切工作正常。现在,一切都按预期进行,只有从此一个收藏夹中移除物品才让我头疼:

  • spring-boot 1.5.13

重构之前:

我在实体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方法进行。

任何帮助/想法都感激!我已经偶然发现了一些等于,哈希码的问题-但是实现了等于,我无法将这些问题与具体问题联系起来。

最诚挚的问候

0 个答案:

没有答案