最初这个问题/错误发布在 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
我有两个实体:Job
和 Step
Job 与 Step 具有 oneToMany 关系,并用 orphanRemoval = True
标记。
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "JOB_STEP")
private List<Step> steps;
预期的行为是,当从 steps
列表中删除某个步骤时,应在 STEP
和 JOB_STEP< 上执行
表。DELETE
查询
第一种情况,执行以下代码时会发生预期的行为:
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
不调用从数据库中删除孤儿时。
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);
执行上述代码后,我仍然可以在数据库中看到STEP和JOB_STEP表中的条目。
打印以下日志:刷新:对 2 个对象进行 0 次插入、0 次更新、0 次删除
几周来我一直试图通过调试 Hibernate 的源代码来找到这个问题的根本原因。但这并没有真正帮助。但是,我注意到一些可能对您有帮助的异常情况:
1) 在调试过程中,我偶然发现了来自 org.hibernate.engine.spi.CollectionEntry
的方法 resetStoredSnapshot
,它本质上只是删除了稍后存储的步骤快照导致 Hibernate 找不到孤儿。而在第一种情况下,当 Hibernate 按预期工作时,resetStoredSnapshot
根本不会执行。
2) 我注意到 java.util.List of Steps 一旦被 Hibernate 转换为 org.hibernate.collection.PersistentList 就开始异常工作
重现错误的工作区在这里:https://github.com/yeralin/ReproduceBug
最佳答案
根据the doc on save :
使用返回的实例进行进一步操作,因为保存操作可能已完全更改实体实例。
你应该这样做:
job = repository.save(job);
step
保存后也可能会有所不同。
要记住这一点,请考虑 @Id
。当您保存实体时,您可能会获得一个具有更新的 ID 的新对象。与step
这样的 child 一样。
关于java - OneToMany 关系孤儿不会从数据库中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48915628/