jpa - 始终打开 EntityManager

标签 jpa entitymanager

我发现了这个问题,Keeping JPA EntityManager open? ,但我还是有一些顾虑。

在应用程序生命周期中始终打开 EnityManager 是个好主意吗?是否消耗数据库连接等资源?如果使用弱引用,它会保留实体还是会释放它们?我使用 EclipseLink 2.x。

谢谢

兹拉亚

最佳答案

EntityManager 被设计得相当短暂。从技术上来说,长时间保持打开状态是可行的,但迟早你会面临以下问题:

  1. 正如您所写的EnityManager 保留加载的实体,实际上它使它们使用弱引用(至少对于 Hibernate 来说是这样,但我不确定这是否是JPA 规范要求)。所以它们应该在 JVM 内存耗尽之前被释放。不幸的是,我发现,当数量增加时,保留大量实体会极大影响 EM 性能(当然是负面影响)。

  2. Open EM 可能消耗数据库连接,例如。当内存中有可延迟加载的对象时。

  3. EM 根据定义不是线程安全的,因此在 Web 应用程序中(例如)重用/共享一个实例是完全 Not Acceptable 。

  4. 可能最大的问题是,当 EM 中发生任何错误时(例如,由于违反数据库约束而导致事务提交),JPA 要求 EM 应尽快关闭并丢弃。这将使驻留在内存中的所有实体处于分离状态,这意味着触摸任何延迟加载的集合/引用都将失败。解决方法是重新加载所有实体,但在较大的应用程序中,当它们分散在应用程序层各处时,这很困难。解决方案是开始使用分离的实体并使用 EntityManager.merge()。但这通常需要更改编程模型,特别是与“始终开放”的实体管理器方法相矛盾。您应该只使用一种方法并坚持下去。

因此,一般来说,最好保持 EntityManager 的生命周期较短,它确实简化了很多事情。

关于jpa - 始终打开 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17424296/

相关文章:

postgresql - 如何在 JPA 中使用 WHERE 子句注释唯一约束

java - SnappyData 作为操作数据库。推荐吗?

java - 如何在 JPA 中持久保存 List<Object> 类型的属性?

java - OpenJPA 在没有 persistence.xml 的代码中创建 EntityManager,具有属性

Hibernate/JPA - 如何在不触发延迟加载的情况下获取@ManyToOne 字段的 id

java - 使用@PersistenceContext(type=PersistenceContextType.EXTENDED) 时避免一级缓存问题

java - 非法参数异常 : Could not locate named parameter

java - 如何持久化每一个新实体?

java - 每次访问数据库时都需要 createEntityManager() 吗?

java - 即使数据库中包含实体,为什么 'EntityManager.contains(..)' 也会返回 false?