Jersey, Guice und Hibernate - Sicherheit von EntityManager-Threads
Ich habe dieses Tutorial auf die gleiche Weise in meiner Anwendung verwendet:http: //www.benmccann.com/hibernate-with-jpa-annotations-and-guice
Meine App ist ein JAX-RS-Webdienst, der viele gleichzeitige Anforderungen empfängt und Aktualisierungen an der Datenbank vornimmt.
GenericDAOImpl.java-Implementierung:
public class GenericDAOImpl<T> implements GenericDAO<T> {
@Inject
protected EntityManager entityManager;
private Class<T> type;
public GenericDAOImpl(){}
public GenericDAOImpl(Class<T> type) {
this.type = type;
}
@Override
public void save(T entity) {
entityManager.getTransaction().begin();
entityManager.persist(entity);
entityManager.getTransaction().commit();
}
}
Wenn 2 Threads gleichzeitig versuchen, eine Entität zu speichern, erhalte ich
java.lang.IllegalStateException: Transaction already active
Speichern funktioniert gut, wenn ich eine Transaktion kommentiere.
Ich habe versucht, @ zu verwend
@Inject
protected Provider<EntityManager> entityManagerProvider;
ode
@Inject
protected EntityManagerFactory entityManagerProvider;
und für jede Anfrage:
EntityManager entityManager = entityManagerProvider.get()
Aber dann bekomme ich:
org.hibernate.PersistentObjectException: detached entity passed to persist
Was ist die richtige Methode zum Implementieren der Guice + Hibernate EntityManager-Klasse für injektions- und threadsichere generische DAOs?
AKTUALISIERE
Andrew Rayner Kommentar vonhttp: //www.benmccann.com/hibernate-with-jpa-annotations-and-guice
"Die Logik ist nicht wirklich produktionsbereit - zumindest wenn sie in einer Web-App verwendet wird.
Hibernates-Verbindungspool ist sehr einfach und noch nicht produktionsbereit. Es wird empfohlen, einen Datenquellenpool wie c3p0 zu verwenden.
EntityManager sollte nicht wiederverwendet werden - es soll pro Transaktion / Anfrage erstellt werden. Es besteht eine gute Chance, dass nachfolgende Anforderungen verschmutzt werden.
Es gibt auch kein Transaktions-Rollback, wenn etwas schief geht.
Ein interessanter Ansatz - für Webanwendungen wäre es jedoch viel sicherer, das Guices-eigene Persist-Erweiterungsmodul zum Verwalten des Lebenszyklus von EntityMananger-Instanzen und -Transaktionen zu verwenden. "