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

标签 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 列表中删除某个步骤时,应在 STEPJOB_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/

相关文章:

hibernate - 从persistence.xml创建实体管理器工厂后如何修改属性

java - 批量插入现有数据 : Preventing JPA to do a select before every insert

java - 从 JSF 访问 JPA 元组属性

java - 上传图片后在 Firebase 中如何获取 Url?

java - 将多个@Id 用于复合主键时出现 Eclipse 错误

javascript - 在java中的 Controller 端处理动态生成的表单元素

sql - to_char函数在Hibernate中引发异常

java - 无法使用 Sdk 23 检查 fragment 中的权限?

java - 使用intellij IDEA的代码库通过windows批处理脚本制作自动jar

java - 为什么我的应用程序不断崩溃