Java JPA无法删除具有onotomany关系和cascatype all的实体

Java JPA无法删除具有onotomany关系和cascatype all的实体,java,jpa,entity,one-to-many,entitymanager,Java,Jpa,Entity,One To Many,Entitymanager,我试图删除一个实体,但当我使用实体管理器时,我没有错误,但te数据仍在数据库中,我使用的是cascade all,独立于此,我将删除其父引用作为 Parent parent = child.getParent(); parent.getChildren().remove(child); entityManager.remove(child); entityManager.merge(parent); 有人知道这样做的方法吗?这可能有几个原因: 您没有从child中删除父引用-child.set

我试图删除一个实体,但当我使用实体管理器时,我没有错误,但te数据仍在数据库中,我使用的是cascade all,独立于此,我将删除其父引用作为

Parent parent = child.getParent();
parent.getChildren().remove(child);
entityManager.remove(child);
entityManager.merge(parent);

有人知道这样做的方法吗?

这可能有几个原因:

您没有从child中删除父引用-
child.setParent(null)
这很重要,因为父
id
可能存储在子表中

调用
merge
时,删除操作尚未提交。这不应该是一个问题,但如果第一个想法没有帮助,我会尝试将删除和合并放在单独的事务中


我假设您使用的是
CascadeType.ALL
,仅在父级上使用。

根据Chris comment编辑,因为它确实一点也不清楚

首先,您必须了解实体实例可以有许多状态

合并用于将实体附加到当前entityManager。一旦它被管理,当EntityManager被刷新时,您对该实体所做的所有修改都将被持久化到数据库中。这通常发生在当前事务结束时(或者当您手动调用flush时,或者当entityManager估计有必要时)

如果您的实体已从当前事务中的数据库中检索,则不需要调用merge,因为它们已被管理

假设这样

你只需要打个电话

entityManager.remove(child);

如果已在关系上配置孤立删除(在父级中)

因此,在刷新当前事务时,而不是在方法调用时,这将自动刷新到数据库

否则,您可以使用
entityManager.flush()
强制刷新,但这是一种不好的做法。无论如何,在提交/关闭事务之前,您不会在数据库中看到更改


如果要使用
entityManager.remove(child)
删除子实体,则必须确保在父实体上应用相关修改(使用
parent.getChildren().remove(child)
,而不是
entityManager.refresh(parent)
),前提是当前正在管理父实例(意味着它实际上在内存中存在父对象的实例,因为您检索了它,或者调用了child.getParent(),或者因为在检索子对象时它被急切地加载。)

您应该维护双向关系的双方,否则该实体与数据库中的内容不同步。如果与被删除实体的关系被标记为cascade persist且未被清理,则可能会无意中恢复实体。@Chris感谢您的更正检查您是否在事务中,并且hat entityManager.flush()将语句推送到数据库。如果您在事务中,则在它提交(或调用flush)之前不会发生任何事情,而如果您不在事务中,则不会发生任何事情-尽管flush会给您一个异常。
parent.getChildren().remove(child);