Ich habe eine Webanwendung, die ein seltsames Verhalten hat, wo ich nicht wirklich meinen Finger aufsetzen kann. Der Kern meines Problems besteht darin, dass die von meinen Ruheendpunkten zurückgegebenen Werte ein inkonsistentes Verhalten aufweisen. Wenn ich meine Anwendung starte, gibt meine Abfrage bei jedem Aufruf dieses Endpunkts dieselben Werte zurück. Wenn ich eine Entität aktualisiere, beginnt sich mein Entitätsmanager merkwürdig zu verhalten. Jetzt beginnt meine Abfrage unterschiedliche Ergebnisse zu liefern. Einmal werden alte Werte anstelle der Werte in der Datenbank zurückgegeben, oder meine Ergebnisliste enthält anstelle von Objekten Proxies (gemischt). jpa2 wiederverwendet entityManager mit guice
Ich habe bestätigt, dass meine @transaction Methoden korrekt platziert sind und in meinem Debug-Stack Ich sehe die Transaktion Interceptor und das Unternehmen Manager pro Anfrage an das Backend erstellt wird (also keine guice Persistenz-Filter)
Meine Gefühl zeigt an, dass das Problem im Sitzungskontext liegt. Ich habe das Gefühl (aber ich kann es nicht wirklich begreifen), dass es meinen Persistenzkontext über mehrere Anfragen wiederverwendet.
Ich habe einige Frameworks zusammen, um das alles funktionieren zu lassen. Ich benutze Resteasy als Jax-Rs-Implementierer. guice (4.0beta4) als cdi implementor und Hibernate als jpa implementor. Da wir beim Einfügen des EntityManagers einen Provider verwenden müssen (da der EntityManager für jede Transaktion erstellt wird), habe ich dies in einen EntityManagerProxy gehüllt. Diese Klasse implementiert die EntityManager-Schnittstelle und delegiert alle Methoden an provider.get(). Method().
public class EntityManagerProxy implements EntityManager {
private final Provider<EntityManager> entityManagerProvider;
@Inject
public EntityManagerProxy(final Provider<EntityManager> entityManagerProvider) {
this.entityManagerProvider = entityManagerProvider;
}
private EntityManager getEntityManager() {
return entityManagerProvider.get();
}
@Override
public void persist(final Object entity) {
getEntityManager().persist(entity);
}
}
Mein guice Modul sieht wie folgt aus
public class OptiWEEEModule extends ServletModule implements Module {
@Override
protected void configureServlets() {
super.configureServlets();
bind(EntityManagerProxy.class);
// JPA
install(new JpaPersistModule("myPU"));
}
}
Ich weiß, dass dies eine vage Frage ist, könnte aber jemand mich in die richtige Richtung helfen? Dies ist nicht wirklich ein Problem, für das ich eine Fehlermeldung ausgeben kann.
edit: Ich habe jetzt Pin auf das Problem hingewiesen. Mit einem Profiler sah ich aus, als ob der Entity Context von Guice wiederverwendet wurde. Dies bedeutet, dass die Abfrage nicht immer ausgeführt wird, sondern der vorhandene Entitätsmanager verwendet wird, der jedes Mal erstellt werden soll, wenn eine @transactional Annotation übergeben wird.
Ich habe gerade von guice 4beta4 zu guice 3 herabgestuft und der gleiche Fehler tritt auf. – jelle
Die Idee von '@ Transactional', dass Sie eine neue Transaktion erhalten, nicht einen neuen EntityManager. Letzteres kann nur wenige davon gut bewältigen. Sie zeigen weder den "update" -Teil Ihres Proxys noch die Webservices, daher ist es schwer zu sagen, was Ihr Problem tatsächlich verursacht. – mabi
Ich habe tatsächlich das Problem niedergebrannt. Nicht der Update-Teil bricht meine Anwendung, aber der Entitymanager wird in jedem Thread wiederverwendet. Ich denke, ich erstelle einen Singleton, der meinen Entitymanager enthält. Könnte mein EntityManagerProxy dies verursachen? Dies ist die Strategie, der ich folge https://code.google.com/p/google-guice/wiki/JPA#Session-per-transaction_strategy – jelle