获取EntityManagerFactory的最佳实践

Evg*_*rov 23 java jpa jndi

在Web应用程序(jsp/servlets)中获取EntityManagerFactory的最佳方法是什么?这是一个好方法何时应该创建/打开EntityManagerFactory实例?或者从JNDI或其他东西获得它更好吗?

Bal*_*usC 62

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

如何做到这一点取决于您的目标容器.它是否支持EJB 3.x(Glassfish,JBoss AS等)?如果是这样,那么如果你只是用@PersistenceContext通常的方式在EJB中执行JPA作业,那么你根本不需要担心打开/关闭它们(对于事务都没有):

@Stateless
public class FooService {

    @PersistenceContext
    private EntityManager em;

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果你的目标容器不支持EJB(例如Tomcat,Jetty等),并且像OpenEJB这样的EJB附加组件由于某种原因也不是一个选项,那么你EntityManager自己手动摆弄创建s(和事务),然后你最好的选择是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();
    }

}
Run Code Online (Sandbox Code Playgroud)

(注意:在Servlet 3.0之前,这个类需要<listener>在in web.xml而不是注册@WebListener)

哪个可以用作:

EntityManager em = EMF.createEntityManager();
// ...
Run Code Online (Sandbox Code Playgroud)

  • @ huahsin68:最初的问题根本不涉及Spring,我也不做Spring.只需按"提问"即可. (3认同)