2011-10-22 47 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