首页 > 解决方案 > 尽管有flush(),但“分离的实体传递给坚持”

问题描述

我有一段长时间运行的 JPA+Hibernate 代码,它试图在循环中将大量记录插入数据库。

随着时间的推移(可能是因为 EntityManager 缓存建立/脏检查),处理速度变得越来越慢。em.flush()为了解决这个问题,我决定em.detach(entity)在每次迭代结束时,因为一旦实体被持久化,我就不需要它的数据进行进一步处理(不幸的是,我不能使用任何一个em.clear()或批处理,以减少我的更改的外部影响)。

这是我的代码的一些粗略草稿:

for (...) {
    ...some selects here...
    ...create new entity object...
    em.persist(entity);
    em.flush();
    em.detach(entity);
}

使用此序列,对于在上一次迭代中分离的实体,我得到了“传递给持久化的分离实体”错误。为什么flush()之前的分离不能防止错误?此外,如果我用 替换detach()clear()一切都会完美运行。我的印象是clear()detach()行为方式一样吗?

更奇怪的是,我可以使用以下代码在一次迭代中重现该错误。第二次刷新会引发“分离的实体...”错误。那么这是否意味着第一次冲洗是空操作?

em.flush();
em.detach(entity);
em.flush();

标签: javahibernatejpa

解决方案


flush()将任何更改与数据库同步,例如,如果您修改了对象和调用flush(),将触发更新。请注意,您通常不必显式调用它,因为刷新通常发生在事务提交时。

如果要减少持久性上下文中的元素数量,则需要调用clear(). 这将实质上重置实体管理器


推荐阅读