Ich benutze Java EE 7. Ich würde gerne wissen, was der richtige Weg ist, eine JPA EntityManager
in eine Anwendung Bereich CDI Bean zu injizieren. Sie können es nicht einfach unter Verwendung der @PersistanceContext
Annotation injizieren, da EntityManager
Instanzen nicht threadsicher sind. Nehmen wir an, wir möchten, dass unsere EntityManager
am Anfang jeder HTTP-Anfrageverarbeitung erstellt und geschlossen wird, nachdem die HTTP-Anfrage verarbeitet wurde. Zwei Möglichkeiten kommen mir in den Sinn:Einen Verweis auf EntityManager in Java EE-Anwendungen mit CDI erhalten
1. Erstellen Sie eine Anfrage bereich CDI Bean, die eine Referenz auf eine EntityManager
hat und dann injizieren Sie die Bohne in einer Anwendung Bereich 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);
}
}
In diesem Beispiel wird ein EntityManager
wird, wenn die RequestScopedBean
erstellt wird erstellt werden, und wird geschlossen, wenn die RequestScopedBean
zerstört wird. Jetzt könnte ich die Injektion in eine abstrakte Klasse verschieben, um sie aus der ApplicationScopedBean
zu entfernen.
2. Erstellen eines Produzenten, die Instanzen von EntityManager
, und dann injizieren die EntityManager
Instanz in eine Anwendung scoped CDI Bean erzeugt.
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);
}
}
In diesem Beispiel werden wir auch eine EntityManager
haben, die jede HTTP-Anforderung erstellt wird, aber was ist die EntityManager
schließen? Wird es auch nach der Verarbeitung der HTTP-Anfrage geschlossen? Ich weiß, dass die @PersistanceContext
Annotation container-verwaltete EntityManager
injiziert. Das bedeutet, dass ein EntityManager
geschlossen wird, wenn eine Client-Bean zerstört wird. Was ist eine Client-Bean in dieser Situation? Ist es die ApplicationScopedBean
, die nie zerstört wird, bis die Anwendung stoppt, oder ist es die EntityManagerProducer
? Irgendwelche Ratschläge?
Ich weiß, dass ich ein stateless EJB verwenden könnte statt Anwendung Bohne scoped und dann injizieren nur EntityManager
durch @PersistanceContext
Anmerkung, aber das ist nicht der Punkt :)
Ich kann das tun und dann 'EntityManager' von der Fabrik in jeder Methode der Anwendung beanspruchte Bean. Aber wird es ein container-verwalteter "EntityManager" sein? Ich denke nicht. Ich möchte den Lebenszyklus eines 'EntityManagers' und Transaktionen nicht selbst verwalten. –
@FlyingDumpling Welche Version von Java EE verwenden Sie? Wenn Sie vor Java EE 7 arbeiten, haben Sie ohnehin keinen Transaktions-Support in CDI-Beans. Siehe diese Antwort: http://stackoverflow.com/questions/17838221/jee7-do-ejb-and-cdi-beans-support-container-managed-transactions –
@AndreiI Sorry, ich habe nicht erwähnt, verwende ich Java EE 7 –