2012-12-31 6 views
9

Ich habe begonnen, Guice-Transaktionen auf Methodenebene wie beschrieben zu verwenden. Ich habe eine Nachricht wieGuice @Transactional startet keine Transaktion

Von der kurzen Beschreibung dachte ich, dass wis genug sein sollte. Aber ich bekomme einen Fehler, weil keine Transaktion gestartet wurde. Es funktioniert nur, wenn ich es selbst beginne und beginne.

Das Objekt wird von Guice am Anfang meiner Anwendung in einem Initialisierer erstellt. Für jede Anfrage wird dieselbe Instanz verwendet.

Warum funktioniert es nicht?

Antwort

6

@Transactional Methode Anmerkungen arbeiten durch AOP, in denen eine Anforderung für Guice Foo erfüllt durch einen Proxy-Objekt zu erzeugen, das diese kommentierten Methodenaufrufe und (optional) dazwischen und leitet sie an das eigentliche Objekt. Stellen Sie sicher, dass die folgenden Bedingungen erfüllt sind:

  1. Sie haben das Objekt mit der @Transactional Methode durch Guice erstellt, da Guice sonst keine Chance hat, den Proxy anstatt zu liefern.

  2. Weder die Klasse noch die Methode ist mit final markiert, da AOP diese nicht einfach überschreiben kann.

  3. Sie haben JpaPersistModule oder eine andere Form von PersistModule installiert. Beachten Sie von diesem Quellcode, dass dieses Modul tatsächlich die MethodInterceptor an die @Transactional Annotation bindet.

Wenn dies nicht Ihren Anforderungen genau passen, denken Sie daran, dass Sie immer mit dem AOP documentation gehen Ihre eigene Methode Abfangjäger zu schreiben. Viel Glück!

+0

"Weder das Objekt noch die Methode wird als endgültig markiert" Sollte das nicht "Weder die * Klasse * noch die Methode ist final" sein? –

+0

Yup, Versprecher. Fest. –

2

Nachdem alles nochmal überprüft wurde, hat es nicht funktioniert. Der lustige Teil ist, dass es zwischendurch funktioniert hat, aber nur alle hundert Mal.

Nach einigen zusätzlichen Tests habe ich festgestellt, dass ich die Klassen bei jeder Anfrage neu erstellen muss. Vorher habe ich sie erst beim Anwendungsstart erstellt. Jetzt scheint es perfekt zu funktionieren.

Dank für Tipps half mir, es weiter zu untersuchen.

0

hatte ich dieses Problem in der folgenden Situation, so dass ich dachte, dass ich hier meine Lösung veröffentlichen würde, auch:

BusinessLogic erfordert zwei Konstruktorargumente: MyDao, die ich theoretisch von guice, und ein anderes Objekt bekommen könnte dass ich nicht von guice bekommen konnte.
Also habe ich eine BusinessLogicProvider (extends AbstactProvider) erstellt, aber es ist nicht mit bind(BusinessLogic.class).toProvider(BusinessLogicProvider) verwendet). Jetzt binde ich nur die BusinessLogicProvider wie jeder guice-served Typ: bind(BusinessLogicProvider.class);

Inside my BusinessLogicProvider Klasse kann ich jetzt @Inject auf ein private Provider<MyDao> daoProvider;

Später verwenden, in den BusinessLogicProvider ‚s public BusinessLogic get() Methode, kann ich dann BusinessLogic nennen 's Konstruktor mit den beiden erforderlichen Argumenten: daoProvider.get() und das andere Objekt kann ich nicht von Guice bekommen.

Die Pitfall: wenn die @Injectprivate Provider<MyDao> daoProvider; meiner BusinessLogicProvider ed nicht vom Typ ist Provider<MyDao> (aber simpy vom Typ MyDao), wird es nicht funktionieren.
Auch wenn die @Inject ed MyDao aus Guice gekommen sind, muss Guice ein neues jedes Mal erstellen Sie BusinessLogic instanziieren.

1

Ich hatte ein ähnliches Problem wie Ihres und es wurde gelöst, indem von @ javax.transaction.Transactional zu @ com.google.inject.persist.Transactional gewechselt wurde. Anscheinend unterstützt Guice-Persist die @ Transactional Annotation von der Java Transaction API nicht.

Verwandte Themen