【发布时间】:2011-12-13 08:16:18
【问题描述】:
在 Web 应用程序(jsp/servlets)中获取 EntityManagerFactory 的最佳方法是什么? 这是一个好方法吗When should EntityManagerFactory instance be created/opened?, 还是从 JNDI 或其他地方获取它更好?
【问题讨论】:
在 Web 应用程序(jsp/servlets)中获取 EntityManagerFactory 的最佳方法是什么? 这是一个好方法吗When should EntityManagerFactory instance be created/opened?, 还是从 JNDI 或其他地方获取它更好?
【问题讨论】:
它们是重量级的,它们应该在应用程序范围内。因此,您需要在应用程序启动时打开它们,并在应用程序关闭时关闭它们。
如何做到这一点取决于您的目标容器。它是否支持 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);
}
// ...
}
如果您的目标容器不支持 EJB(例如 Tomcat、Jetty 等),并且出于某种原因,像 OpenEJB 这样的 EJB 插件也不是一个选项,因此您需要手动摆弄创建 @987654327 @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();
}
}
(注意:在Servlet 3.0之前,这个类需要<listener>在web.xml注册,而不是@WebListener)
可以用作:
EntityManager em = EMF.createEntityManager();
// ...
【讨论】:
Persistence类的全名吗?