OneToMany关系孤儿不会从数据库中删除

时间:2018-02-21 21:17:09

标签: java hibernate jpa

最初在Hibernate的JIRA上发布了这个问题/错误:https://hibernate.atlassian.net/browse/HHH-12311

我的日志属性设置为:

logging.level.org.hibernate.SQL: TRACE
logging.level.org.hibernate.event.internal: TRACE
logging.level.org.hibernate.engine.spi.CollectionEntry: TRACE
logging.level.org.hibernate.engine.spi: TRACE
logging.level.org.hibernate.engine.internal: TRACE

我有两个实体:JobStep Job与Step具有oneToMany关系,标记为orphanRemoval = True

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "JOB_STEP")
private List<Step> steps;

预期的行为是从steps列表中删除某个步骤时,应在DELETESTEP表上执行JOB_STEP个查询。

第一种情况,执行以下代码时会发生预期的行为:

Job job = new Job("Test");
Step step = new Step("Test");
job.addStep(step);
repository.save(job);
job.removeStep(step);
repository.save(job);

我看到三条预期的日志消息:

o.h.e.i.AbstractFlushingEventListener: Flushed: 0 insertions, 0 updates, 1 deletions to 2 objects
org.hibernate.SQL: delete from job_step where job_id=?
org.hibernate.SQL: delete from step where id=?

第二种情况,orphanRemoval = true没有调用从DB中删除孤儿。

Job job = new Job("Test");
Step step = new Step("Test");
repository.save(job); //This causes the bug to happen
job.addStep(step);
repository.save(job);
job.removeStep(step);
repository.save(job);

执行上述代码后,我仍然可以在DB中查看STEP和JOB_STEP表中的条目。

打印以下日志:Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects

我通过调试Hibernate的源代码,几周来一直试图找到这个问题的根本原因。但它并没有真正帮助。但是,我注意到一些可能对你有帮助的异常事情:

1)在调试过程中,我偶然发现了来自resetStoredSnapshot的这个方法org.hibernate.engine.spi.CollectionEntry,它基本上只是擦除了存储的步骤快照,后来导致Hibernate不能找到孤儿。在第一种情况下,当Hibernate按预期工作时,resetStoredSnapshot根本不会执行。

2)我注意到一步的java.util.List在被Hibernate转换为org.hibernate.collection.PersistentList后开始异常工作

带有重现错误的工作区位于:https://github.com/yeralin/ReproduceBug

1 个答案:

答案 0 :(得分:2)

根据the doc on save

Use the returned instance for further operations as the save operation might have changed the entity instance completely.

你应该这样做:

job = repository.save(job);
保存后,

step也可能有所不同。

要记住这一点,请考虑@Id。保存实体时,可能会获得具有更新ID的新对象。与step等孩子相同。