Search code examples
javaspringspring-boottransactional

@Transactional proxyTargetClass and @Inherited


I have 2 questions where I can't figure answers for them regarding @Transactional:

1- @Transnational on interface
as per answers :

If you have your app set to proxy-target-class='true' (in your application context, then your @Transactional information wont be picked up if you annotate the Interface.

I configured my application.properties with :

spring.aop.proxy-target-class=true

and the annotation on interface still picked up , I have tried also the following ( proxyTargetClass = true on EnableTransacationManagement ) :

@SpringBootApplication
@EnableAsync
@EnableTransactionManagement(proxyTargetClass = true)
public class Application extends SpringBootServletInitializer {
}

still the @Transnational is working where I'm configuring only on interface , so what am I missing here ?

2- @Transnational has @Inherited, the @inherited as per java doc :

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

I have the following interface annotated with @Transnational and it's still working on the interfaces extending it :

@Repository
@Transactional
public interface UserRepository extends JpaRepository<User, Long> {


}

The following/below interface has modifying query where it won't work without @Transactional, I have annotated the interface above with @Transacational and it's being picked up ( it even works if I configure on parent methods instead of class ) :

public interface TestRepository extends UserRepository {

@Query("UPDATE User U set U.name='hello' where U.id=1")
@Modifying
public void test();

}

so how the transaction worked if the @Inherited doesn't have effect on interface ?


Update : for Question 1

I even tried @Async on interface method and it worked without annotating implementing class , the AOP is working with CGLIB proxies ( when annotating interface methods only ) this is contradiction with most of the answers not sure if there is anything wrong.


Solution

  • The answer you link to is for Spring 3.0 however currently we are at Spring 5.1. This is roughly 7 versions ahead and that section of the reference guide doesn’t exist anymore.

    It doesn’t matter which proxy mode you use Spring will always try to find the @Transactional annotation on implementing interfaces when not found on the implementation. This is Spring behavior and specially implemented in Spring, this deviates from the default annotation inheritance rules. (Normally when doing getAnnotation this wouldn’t work, so Spring implemented this). See also this section of the Spring reference guide.

    Next to that you also use Spring Data JPA, which also adds metadata and annotation processing specially for the dynamic repositories it creates.