As discussed here:
http://forum.springframework.org/showthread.php?p=139502
Given the following context:
. an application built with compile-time weaving using AspectJ 1.5.x,
. use of Spring 2.0.x
. a class annotated with @Transactional - not its methods,
. the same class containing one or more setters for dependency injections,
. a Spring application context declaring the above class with a singleton scope and its dependencies through property references
. the same application context using the <tx:annotation-driven /> tag
Upon loading the application context and instantiating the annotated class, the container tries to begin a transaction but fails with the following message:
java.lang.IllegalStateException: Property 'transactionManager' must be set on transaction aspect
The current behavior is understandable: the class was annotated in such a way that all its public methods should be transactional, which includes the DI setters. However this doesn't seem to be desirable, given the thrown exception.
One possible workaround is to annotate only the transactional methods (and so not the DI setter methods) instead of the class itself. The main drawback is that this leads to the duplication of the annotation and its list of rollback exceptions. It also requires that all unit tests which operate on the annotated class should provide the AnnotationTransactionAspect a mock PlatformTransactionManager on setUp().
One possible solution would be to activate the transactional aspect only after the application context is loaded. Another one would be to introduce a @NotTransactional annotation that would override the class annotation and that could be used on DI setter methods.
The disadvantage is that you won't immediately notice when your transaction aspect is not active at runtime. I guess that's acceptable, since you won't notice when you didn't activate proxying either. Effectively this is a slight redefinition of the aspect's role: Weaving it in means that it can be active at runtime - but it doesn't have to be; the choice is up to the configuration.
As for the redundancy of rollback rules: This demands a more general solution for sharing common rollback rules. I recommend applying @Transactional at the method level, but I agree that this is only really feasible if you don't have any rollback rules - or have a way to share your rollback rules.
Juergen