最初在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
列表中删除某个步骤时,应在DELETE
和STEP
表上执行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
答案 0 :(得分:2)
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
等孩子相同。