Я использую Java EE 7. Я хотел бы знать, как правильно вводить JPA EntityManager
в приложение CDI bean. Вы не можете просто вводить его с помощью аннотации @PersistanceContext
, потому что экземпляры EntityManager
не являются потокобезопасными. Предположим, что мы хотим, чтобы наш EntityManager
был создан в начале каждой обработки HTTP-запроса и закрыт после обработки 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
. Это означает, что EntityManager
будет закрыт, когда клиент bean будет уничтожен. Что такое клиент bean в этой ситуации? Это ApplicationScopedBean
, который никогда не будет уничтожен до тех пор, пока приложение не остановится, или это будет EntityManagerProducer
? Любые советы?
Я знаю, что я мог бы использовать независимый EJB без приложения scoped bean, а затем просто вставлять EntityManager
by @PersistanceContext
аннотацию, но это не точка:)