This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
I am currently trying to use the @Transactional annotation within my application and I seem to have some problems.
I have a perfectly running application where the advices and pointcuts are defined in the xml files.
To switch to use the @Transactional annotation and remove the xml files.
I started with a single interface and its implementation class
Within my applicationContext.xml I have used
When @Transactional is used on concrete class the code works fine
but when the same is used on an interface or methods of an iterface it does not seem to work as it should or so it seems.
On further reading the spring source reference I came to know that
Extract from the spring source ::
To be clear: using 'proxy-target-class="true"' on <tx:annotation-driven/>, <aop:aspectj-autoproxy/> or <aop:config/> elements will
force the use of CGLIB proxies for all three of them.
The CGLIB proxies are class based proxies
and though I was using proxy-target-class="false" with the <tx:annotation-driven/>
my applicationContext-aop had proxy-target-class="true" and hence class based proxies was being used and so it could not detect the @Transactional settings of the interface
So I commented all the advices and pointcuts within my xml files and changed the proxy-target-class setting to false within my applicationContext-aop.xml
and I have placed the @Transactional annotation before my interface definitions as follows (shown here for only one interface)
and I have also place it on the Service interface also.
Now when I start my application I am getting the following exception (Fragments of my exception) :
There is a bean SampleValidator which takes as a constructor argument the SampleServiceImpl.
This is having some problem
AFAIK you should dependency inject interfaces and not the implementation. You should annotate the implementation with @Transactional and not the interface.
The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies. The fact that annotations are not inherited means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj") then the transaction settings will not be recognised by the proxying/weaving infrastructure and the object will not be wrapped in a transactional proxy (which would be decidedly bad). So please do take the Spring team's advice and only annotate concrete classes (and the methods of concrete classes) with the @Transactional annotation.
Spring uses interface based proxies (if on java 5 or above) by default.
If you annotate the interface, and inject the interface, the result will be a J2SE dynamic proxy unless one has specified: proxy-target-class="true" on one of the aop configuration elements or one is on java 1.4 or below. But this you seem to already know Annotations are not inherited (unless otherwise specified. I just read this: Blog from 2007 ).
The annotation on the Service interface will not have any affect at all for what i can understand.
You are getting the same error? (I modified it to SampleService)
when you have the annotation on the interface, inject the interface and have proxy-target-class="false" ?
Joined: Mar 19, 2008
Thanks for the reply Svein
That was a question you are asking me or are you telling me what to do?
If that is what you are telling me to do then I have some problem again
Because injecting the interface is a problem because my implementation class (which implements the interface) takes a SampleDao
and so I need to inject to the SampleService the appropriate sampleDao bean. If I were passing the interface instead of the implementation class
I will not be able to inject the dao bean.
Thanks in advance
Joined: Mar 19, 2008
Thank you so much for your help.
I got to know what you meant.
The property within my class was the implementation class and not the interface and hence the problem
Just by changing the property to use the interface solved my problem.
Thank you once again for the timely help
Thanks JavaRanch for this wonderful site