休眠删除实体问题

Posted

技术标签:

【中文标题】休眠删除实体问题【英文标题】:Hibernate deleteEntity issues 【发布时间】:2014-12-05 11:01:46 【问题描述】:

有两个域对象(我们称它们为 A 和 B)同样使用 Hibernate 进行删除/删除。

我只能删除 A 而不是 B 对象,并且没有异常,也没有报告任何错误的日志记录。 两种对象类型都使用相同的服务方法进行删除。

public void delete(T instance) 
    getEntityManager().remove(instance);

我已经深入到 B 停止的位置,并且 A 能够进一步成功删除。 而B停在课堂@987654321@;这意味着 @Override public void execute() throws HibernateException 永远不会在 @987654322@ 中为 B 调用方法。

找不到execute方法的用法,对比了各个阶段的状态,没有发现异常(可能有)。

任何人都有使用 Hibernate/EntityDeleteAction 的经验并且可以告诉我问题可能是什么?

更新

我找到了为什么 B 不会删除的原因。那是因为 A 引用了 B 的集合。 这个集合是急切地加载而不是懒惰地加载。这段代码说明了这一点:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "a", targetEntity = B.class, cascade = CascadeType.ALL)
private Set<B> bCollection = new HashSet<B>();

更改为FetchType.LAZY 即可删除。但是在这个应用程序中,我们不保持 hibernate/jpa 会话打开,因此如果在会话关闭后它试图恢复延迟加载,延迟加载将无法在应用程序的其他部分工作。 所以我们找到了原因,但没有找到解决方案,因为我们想保持快速加载。

这是一种在删除之前将 B 从 A 中分离出来的方法吗?导致问题的是从 A 到 B 的主动引用。

【问题讨论】:

在致电remove() 之前尝试getEntityManager().refresh(instance)。另外,你能发布调用这个delete()方法的代码吗? @PredragMaric 我用更多信息更新了帖子。 A 使用 FetchType.EAGER 加载 B 的集合。通过更改为 LAZY 然后删除将起作用。但是我们在使用 LAZY 时也遇到了问题,我们希望找到一种方法让它与 EAGER 加载一起工作。顺便说一句,刷新实例不起作用。 奇怪,没遇到过这样的问题。如果你用 HQL 删除它怎么办? "delete from B where id = " + b.getId() 查询没问题。我现在发布了解决方案。 【参考方案1】:

在删除调用后尝试刷新并启用 Hibernate SQL 日志记录。

【讨论】:

我试过刷新和刷新,但没有运气。我更新了我原来的帖子。【参考方案2】:

解决方案只是在从数据库中删除之前从 A 中的集合中删除 B,从而从 A 中删除对 B 的引用,这就是问题所在。

collectionOfBObjects.remove(b);

【讨论】:

以上是关于休眠删除实体问题的主要内容,如果未能解决你的问题,请参考以下文章

删除实体时休眠将外键设置为空

无法使用休眠删除将集合作为子项的实体

如何在多对多关系上使用休眠和 JPA 删除孤立实体?

如果在实体中添加或删除列,则使缓存无效(2LD 缓存休眠)。 (雷迪森)

休眠一对多关联删除

休眠:加入带有额外列的表,从一侧删除子项