我发现了这个问题,保持 JPA EntityManager 打开?,但我还是有些担心。
在应用程序生命周期中始终打开 EnityManager 是个好主意吗?它会消耗一些资源,例如数据库连接吗?如果它使用弱引用,它会保留实体还是会释放它们?我使用 EclipseLink 2.x。
谢谢
兹拉亚
我发现了这个问题,保持 JPA EntityManager 打开?,但我还是有些担心。
在应用程序生命周期中始终打开 EnityManager 是个好主意吗?它会消耗一些资源,例如数据库连接吗?如果它使用弱引用,它会保留实体还是会释放它们?我使用 EclipseLink 2.x。
谢谢
兹拉亚
EntityManager 被设计为相当短暂的。从技术上讲,长时间保持打开状态是可行的,但迟早您会面临以下问题:
正如您所写的那样,EnityManager
保持加载的实体,实际上它使用弱引用来保持它们(至少在 Hibernate 中,但我不确定这是否是 JPA 规范所要求的)。所以它们应该在 JVM 内存不足之前被释放。不幸的是,我发现当数量增加时,保持大量实体会极大地影响 EM 性能(当然是负面的)。
Open EM 可能会消耗一个数据库连接,例如。当内存中有可延迟加载的对象时。
根据定义,EM不是线程安全的,因此在 Web 应用程序中(例如)重用/共享一个实例是完全不可接受的。
可能最大的问题是当 EM 中发生任何错误时(例如,由于违反 DB 约束而导致的事务提交),JPA 要求 EM 应尽快关闭并丢弃。这会将驻留在内存中的所有实体置于分离状态,这意味着触摸任何延迟加载的集合/引用都将失败。一种解决方法是重新加载所有实体,但在较大的应用程序中,当它们分散在应用程序层中时,这很困难。一个解决方案是开始使用分离的实体并使用EntityManager.merge()
. 但这通常需要更改编程模型,特别是与“始终开放”的实体管理器方法有些矛盾。您应该只使用一种方法并坚持下去。
所以通常最好保持EntityManager
短暂,它确实简化了很多事情。