【发布时间】:2026-02-06 21:25:01
【问题描述】:
我正在使用 Java EE 7。我想知道将 JPA EntityManager 注入 应用程序范围 CDI bean 的正确方法是什么。您不能只使用 @PersistanceContext 注释注入它,因为 EntityManager 实例不是线程安全的。假设我们希望在每个 HTTP 请求处理开始时创建 EntityManager,并在处理 HTTP 请求后关闭。我想到了两个选择:
1。
创建一个请求范围的 CDI bean,它具有对 EntityManager 的引用,然后将该 bean 注入应用程序范围的 CDI bean。
import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@RequestScoped
public class RequestScopedBean {
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
}
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
@ApplicationScoped
public class ApplicationScopedBean {
@Inject
private RequestScopedBean requestScopedBean;
public void persistEntity(Object entity) {
requestScopedBean.getEntityManager().persist(entity);
}
}
在此示例中,EntityManager 将在创建 RequestScopedBean 时创建,并在 RequestScopedBean 销毁时关闭。现在我可以将注入移动到某个抽象类,以将其从ApplicationScopedBean 中删除。
2。
创建一个产生EntityManager 实例的生产者,然后将EntityManager 实例注入应用程序范围的CDI bean。
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class EntityManagerProducer {
@PersistenceContext
@Produces
@RequestScoped
private EntityManager entityManager;
}
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
@ApplicationScoped
public class ApplicationScopedBean {
@Inject
private EntityManager entityManager;
public void persistEntity(Object entity) {
entityManager.persist(entity);
}
}
在此示例中,我们还将有一个 EntityManager,它会在每个 HTTP 请求中创建,但是 关闭 EntityManager 呢?处理完HTTP请求后也会关闭吗?我知道@PersistanceContext 注释注入了容器管理的EntityManager。这意味着当客户端 bean 被销毁时,EntityManager 将被关闭。在这种情况下,什么是客户端 bean?是ApplicationScopedBean,在应用程序停止之前永远不会被销毁,还是EntityManagerProducer?有什么建议吗?
我知道我可以使用无状态 EJB 代替应用程序范围的 bean,然后通过 @PersistanceContext 注释注入 EntityManager,但这不是重点 :)
【问题讨论】:
标签: java jpa cdi entitymanager java-ee-7