jpa - Guice Persist 是否提供事务范围或应用程序管理的 EntityManager?

标签 jpa guice entitymanager guice-persist

我们使用 Guice Persist在我们的项目中注入(inject) EntityManager。

例如。

public class MyDao{
   @Inject
   EntityManager em;

   public void someMethod(){
       //uses em instance
   }
}

但我们不清楚 EntityManager 的实例是如何注入(inject)的。即将使用。
  • 这是什么类型的EntityManager? (参见例如:types of entity managers )Guice Persist 通过 EntityManagerFactory.createEntityManager() 实例化它。所以我会说它是应用程序管理的实体管理器。但是在 official Wiki他们写了关于每笔交易的 Seesion 策略,这表明 EntityManager 是(伪)事务范围的。
  • 我们是否应该手动调用 close() ?还是 Guice 会处理它?
  • first level cache的范围是什么? 仅单个事务(如在事务范围的实体管理器中)或只要我使用 EntityManager 的相同注入(inject)实例(比如在应用程序管理的实体管理器中)?
  • 最佳答案

    尽管 Piotr 完美地回答了这个问题,但我想就如何使用 guice-persist 添加一些实用建议。

    我一直遇到一些很难调试的问题。在我的应用程序中,某些线程会显示过时的数据,有时会显示 EntityManager实例留下了旧的死数据库连接。根本原因在于我使用 @Transactional 的方式。注释(我只将它们用于执行更新/插入/删除的方法,而不是用于只读方法)。 guice-persist 商店EntityManager ThreadLocal 中的实例只要您调用get()在注入(inject) Provider<EntityManager>实例(我为只读方法所做的)。然而,这个 ThreadLocal仅当您还调用 UnitOfWork.end() 时才会删除(如果 @Transactional 在方法上,通常由拦截器完成)。不这样做会将 EM 实例留在 ThreadLocal 中,因此最终线程池中的每个线程都将拥有一个带有陈旧缓存实体的旧 EM 实例。

    因此,只要您遵守以下简单规则,guice-persist 的使用就很简单:

  • 始终注入(inject) 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/

    相关文章:

    jboss - 在 JNDI Jboss Seam 中找不到 EntityManagerFactory

    java - QueryDSL 获取另一个实体集合中的任何实体

    jpa - 为什么 LocalXAResourceImpl.commit() 中的异常仅给出警告?

    mysql - 一张表的SQL算术运算

    java - CDI 是否为默认生产者提供 API?

    java - 什么时候安装 Guice 模块?

    java - JPA 2 case 语句允许构造函数查询中为 null

    java - 在 Spring MVC 应用程序中使用 jclouds 创建 BlobContext 时出错

    java - 获取 java.lang.ExceptionInInitializerError

    java spring jpa使用entityManager.clear()时没有在数据库表中保存任何内容