2012-07-16 68 views
0

在查询对象或删除/创建对象时,我很难理解实体管理器的正确用法。眼下对于任何数据库事务我有一个打开几个服务的方法和新的接近实体管理器,像这样:从EntityManagerFactory正确使用实体管理器

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; 
} 

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

更新:

我使用下面的堆栈,Spring框架/ JPA的EclipseLink

+1

'EntityManager'不是线程安全的。 – 2012-07-16 23:46:19

+0

所以通过关闭它每次我避免锁定问题? – Warz 2012-07-16 23:59:51

+0

我对这个东西一无所知,但我想我注意到一种内存泄漏形式,EntityManager中的对象缓存持续增长。 – 2012-07-17 00:02:10

回答

2

长话短说:既然你使用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配置文件中的配置问题。

+0

这是否意味着我不需要明确地关闭它们了? – Warz 2012-07-17 03:00:44

+0

是的,这是由Spring提供的EM管理的 – 2012-07-17 12:48:06

1

的EntityManager时,应用程序管理的一般不是线程安全的。

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

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

@PersistenceContext 
EntityManager entityManager; 

春天是一个这样的容器,可以做到这一点。上面的链接是一个有用的资源。