Die Injektion autowierter Abhängigkeiten ist bei der Verwendung von @Transactional fehlgeschlagen

7

Ich habe mein DAO getestet, aber es hat nicht funktioniert. Der folgende Fehler tritt auf:

%Vor%

Mein DAO:

%Vor%

Mein Test für dieses DAO:

%Vor%

Meine applicationContext.xml :

%Vor%

Ich bemerke, dass wenn Sie @Transactional in DAO kommentieren, Bean korrekt erstellt wird. Was passiert?

    
tsekhan 22.03.2012, 02:49
quelle

2 Antworten

22

Vor allem ist es wirklich schlecht, einen Namen zu geben, der in Controller endet, ein sehr verwirrender DAO, Controller und DAO haben alle zusammen einen anderen Zweck.

Wenn Sie @Transactional zu einer Service- oder DAO-Klasse hinzufügen, muss der Spring, um in einer Transaktion arbeiten zu können, einen Proxy dieser Klasse erstellen. Dies ist eine Art Wrapper, in der vor der Ausführung der proxied-Klasse (Klasse in Gegenleistung, die proxied ist) method spring startet die Transaktion und nach der Ausführung, falls keine Ausnahmen die Transaktion abschließen, kann dies im Frühjahr über AOP und Annotationen erfolgen. Um im Code zu beschreiben.

%Vor%

Wie Sie sehen, handelt es sich hierbei nicht um eine exakte Implementierung, sondern um einen Basiscode, wie die Transaktion auf magische Weise für Sie funktioniert. Der entscheidende Punkt ist die Schnittstelle OriginalDao, die diese Injektion erleichtert, da OriginalDaoImpl und ProxyDaoImpl beide dieselbe Schnittstelle implementieren. Daher können sie ausgetauscht werden, d. H. Proxy statt Original. Dieser dynamische Proxy kann in Java vom Java Dynamic Proxy erstellt werden. Nun, die Frage, was ist, wenn Ihre Klasse keine Schnittstelle implementiert, wird es schwieriger für die Ersetzung zu passieren. Eine der Bibliotheken CGLIB, soweit ich weiß, hilft in solch einem Szenario, wobei es eine dynamische Unterklasse für die betrachtete Klasse erzeugt und in der overriden-Methode die Magie wie oben beschrieben ausführt, indem sie super.save(o) an den ursprünglichen Code delegiert.

Nun zum Problem der Injektion.

  1. Erstellen Sie eine Schnittstelle und lassen Sie Ihr Dao dies implementieren und spring wird standardmäßig auf den JDK-Proxy umstellen, so wie es sich jetzt verhält.
  2. % proxy-target-class="true" Attribut zu <tx:annotation-driven transaction-manager="transactionManager"/> hinzufügen

Was die Ausnahme betrifft, wird geworfen, da es erwartet, dass injizierte Bean vom Typ 'HibernateController' ist, aber nicht.

Als Referenz können Sie die folgenden Links verwenden.

  1. 10.5.6 Verwenden von @Transactional
  2. Spring AOP Doc

Hoffe das hilft !!!!!.

    
baba.kabira 22.03.2012, 05:17
quelle
0

Wenn Sie Spring MVC verwenden, stellen Sie sicher, dass Sie nur bestimmte Controller-Klassen in servlet context file scannen. Andernfalls wird 2 mal gescannt und die Transaktion ist im Anwendungskontext nicht verfügbar.

    
Anbarasan 15.10.2012 06:41
quelle