【问题标题】:Proper Usage of Entity Manager from EntityManagerFactoryEntityManagerFactory 中实体管理器的正确使用
【发布时间】:2012-07-16 23:41:29
【问题描述】:

在查询对象和/或删除/创建时,我无法理解实体管理器的正确用法。现在对于任何数据库事务,我有几个服务方法可以打开和关闭新的实体管理器,如下所示:

public static Long getCountApplicants(String active){

    EntityManager entityManager = factory.createEntityManager();
    long value = (Long) entityManager.createQuery("select count(distinct a) from    Applicant a  where a.active = " +active).getSingleResult();
    System.out.println("get count app query");
    entityManager.close();
    return value;
}

既然我有一个 Java EE 应用程序,其中包含一个定义我的单元的 persistence.xml 文件,为什么我不能从我的工厂声明一个并在我的应用程序的整个生命周期中使用它?仅使用其中一个对象是否存在任何性能或内存泄漏问题?

更新:

我正在使用以下堆栈,Spring Framework/JPA Eclipselink

【问题讨论】:

  • EntityManager 不是线程安全的。
  • 所以每次我避免锁定问题时都关闭它?
  • 我对这些东西也一无所知,但我想我注意到了一种内存泄漏形式,EntityManager 中的对象缓存继续增长。
  • 这与我在测试环境中注意到的完全相同。使用 spring 框架,我从“EMF”中获得了持续的缓存实例调用,并且每隔一段时间就会减慢我的查询速度。

标签: java jpa eclipselink entitymanager


【解决方案1】:

长话短说:由于您使用的是 Spring,因此最好将实体管理器定义为您的 DAO 的属性,如下所示:

@PersistenceContext
EntityManager em;

然后你的代码变成:

public static Long getCountApplicants(String active){
    long value = (Long) em.createQuery("select count(distinct a) from    Applicant a  where a.active = " +active).getSingleResult();
    System.out.println("get count app query");
    return value;
}

这仅适用于非扩展持久性上下文。
Spring 注入的 EntityManager 将是线程安全的。
是否需要配置 LocalEntityManagerFactorBean 应用程序管理或 LocalContainerEntityManagerFactoryBean 容器管理的实体管理器,只是在 Spring 配置文件中配置的问题。

【讨论】:

  • 这是否意味着我不再需要显式关闭 em 了?
【解决方案2】:

EntityManager 在应用程序管理时通常不是线程安全的。

http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html

但是,如果您使用的是容器管理版本,则应该如此。你会注入它:

@PersistenceContext
EntityManager entityManager;

Spring 就是这样一种可以做到这一点的容器。上面的链接是一个有用的资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-29
    • 2011-12-03
    • 2012-05-21
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2019-11-23
    相关资源
    最近更新 更多