Java 获取EntityManagerFactory的最佳实践

Java 获取EntityManagerFactory的最佳实践,java,jpa,jndi,Java,Jpa,Jndi,在web应用程序(jsp/servlet)中获取EntityManagerFactory的最佳方法是什么? 这是个好办法吗, 还是从JNDI或其他什么地方获得它更好?它们是重量级的,应该在应用范围内。所以,您需要在应用程序启动时打开它们,在应用程序关闭时关闭它们 如何做到这一点取决于您的目标容器。它是否支持EJB3.x(Glassfish、JBossAS等)?如果是这样的话,那么您根本不需要担心打开/关闭它们(也不需要担心事务),如果您只是以通常的方式在EJB中执行JPA工作: @Statele

在web应用程序(jsp/servlet)中获取EntityManagerFactory的最佳方法是什么? 这是个好办法吗,
还是从JNDI或其他什么地方获得它更好?

它们是重量级的,应该在应用范围内。所以,您需要在应用程序启动时打开它们,在应用程序关闭时关闭它们

如何做到这一点取决于您的目标容器。它是否支持EJB3.x(Glassfish、JBossAS等)?如果是这样的话,那么您根本不需要担心打开/关闭它们(也不需要担心事务),如果您只是以通常的方式在EJB中执行JPA工作:

@Stateless
public class FooService {

    @PersistenceContext
    private EntityManager em;

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

    // ...
}
如果您的目标容器不支持EJB(例如Tomcat、Jetty等),并且类似EJB的附加组件出于某种原因也不是一个选项,因此您需要自己手动创建
EntityManager
s(和事务),那么您的最佳选择就是创建。以下是一个基本的启动示例:

@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之前,此类需要通过
web.xml
中的
注册,而不是

它可以用作:

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

一如既往,这是一个很好的例子,但我只是想补充一点,当使用@PersistenceContext而不使用“unitName”属性时,它意味着(以非声明性的方式)使用“persistence.xml”中定义的唯一/默认持久性单元。如果有多个数据源/持久性单元,可能会导致混淆这是哪一个。不确定还缺少什么,我按照您的回答回答,但存在运行时错误?>原因:org.springframework.beans.factory.NoSuchBean定义异常:未定义类型为[javax.persistence.EntityManagerFactory]的唯一bean:预期为单个bean,但找到0:@huahsin68:原始问题根本不涉及Spring,我也不涉及Spring。只需按“提问”。您能给出
持久性
类的全名吗?