2011-10-22 91 views

回答

57

他们是重量级的,他们应该是在应用范围。因此,您需要在应用程序启动时打开它们,并在应用程序关闭时关闭它们。

如何做到这一点取决于你的目标容器。它支持EJB 3.x(Glassfish,JBoss AS等)吗?如果是这样,那么你就不需要担心开/关他们(既不有关事务)在所有如果你只是做在EJB中的JPA工作与@PersistenceContext通常的方式:

@Stateless 
public class FooService { 

    @PersistenceContext 
    private EntityManager em; 

    public Foo find(Long id) { 
     return em.find(Foo.class, id); 
    } 

    // ... 
} 

如果你的目标容器没有按不支持EJB(例如Tomcat,Jetty等)和像OpenEJB这样的EJB插件也不是一个选项,因此你自己手动摆弄自己创建EntityManager(和事务),那么你最好的选择是一个ServletContextListener。这里有一个基本开球例如:

@WebListener 
public class EMF implements ServletContextListener { 

    private static EntityManagerFactory emf; 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     emf = Persistence.createEntityManagerFactory("unitname"); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
     emf.close(); 
    } 

    public static EntityManager createEntityManager() { 
     if (emf == null) { 
      throw new IllegalStateException("Context is not initialized yet."); 
     } 

     return emf.createEntityManager(); 
    } 

} 

(注:Servlet的3.0之前,这个类需要由<listener>@WebListenerweb.xml,而不是注册)

哪些可以作为:

EntityManager em = EMF.createEntityManager(); 
// ... 
+0

非常好的例子,但只是想补充说,当使用不带“unitName”属性的@PersistenceContext时,它意味着(我n非声明性方式)使用“persistence.xml”中定义的唯一/默认持久性单元。如果存在多个数据源/持久性单元,则可能导致混淆这是哪一个。 –

+0

不知道还有什么遗漏,我按照你的答案,但有一个运行时错误? >导致:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义[javax.persistence.EntityManagerFactory]类型的唯一bean:期望的单个bean但是找到0: – huahsin68

+3

@ huahsin68:原始问题根本不涉及Spring我也不会做Spring。只需按“提问”即可。 – BalusC