我们使用 Guice Persist在我们的项目中注入(inject) EntityManager。
例如。
public class MyDao{
@Inject
EntityManager em;
public void someMethod(){
//uses em instance
}
}
但我们不清楚
EntityManager
的实例是如何注入(inject)的。即将使用。EntityManagerFactory.createEntityManager()
实例化它。所以我会说它是应用程序管理的实体管理器。但是在 official Wiki他们写了关于每笔交易的 Seesion 策略,这表明 EntityManager 是(伪)事务范围的。 EntityManager
的相同注入(inject)实例(比如在应用程序管理的实体管理器中)? 最佳答案
尽管 Piotr 完美地回答了这个问题,但我想就如何使用 guice-persist 添加一些实用建议。
我一直遇到一些很难调试的问题。在我的应用程序中,某些线程会显示过时的数据,有时会显示 EntityManager
实例留下了旧的死数据库连接。根本原因在于我使用 @Transactional
的方式。注释(我只将它们用于执行更新/插入/删除的方法,而不是用于只读方法)。 guice-persist 商店EntityManager
ThreadLocal
中的实例只要您调用get()
在注入(inject) Provider<EntityManager>
实例(我为只读方法所做的)。然而,这个 ThreadLocal
仅当您还调用 UnitOfWork.end()
时才会删除(如果 @Transactional
在方法上,通常由拦截器完成)。不这样做会将 EM 实例留在 ThreadLocal 中,因此最终线程池中的每个线程都将拥有一个带有陈旧缓存实体的旧 EM 实例。
因此,只要您遵守以下简单规则,guice-persist 的使用就很简单:
Provider<EntityManager>
而不是 EntityManager
直接地。 @Transactional
注释每个方法(甚至是只读方法)。这样 JpaLocalTxnInterceptor
将拦截对带注释的方法的调用,确保不仅启动和提交事务,而且在 ThreadLocal 中设置和取消设置 EM 实例。 PersistFilter
guice-persist 附带的 servlet 过滤器。它将调用 begin()
和 end()
在 UnitOfWork
在请求完成之前和之后为您服务,从而填充和清理 ThreadLocal。 希望这可以帮助!
关于jpa - Guice Persist 是否提供事务范围或应用程序管理的 EntityManager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18101488/