9
votes

I'm working on a very small application connecting to a MySQL database.

I'm trying to create table record but getting 'no transaction in progress'.

I have all the right stuff in place:

  • a service interface MyService and its implementation MyServiceImpl
  • I have annotated the service impl with @Service
  • In the controller I used the interface name for the field @Autowired MyService
  • I have the correct transaction configuration as it was originally generated by roo
  • There is a public method MyService.create(...) which MyServiceImpl implements

But,

When I remote debug and inspect the controller's myService field what I see is something like com.some.package.services.MyService@12345 (and NOT something like $Proxy73) which to me is not right, because what should be autowired is the proxy not he target bean (which is what I think this is). If I'm correct then it makes sense that there is no transaction as the annotation would only kick in when invoking a public method annotated with @Transactional on a proxy.

Please tell me why is spring injecting the target bean in this setup.

Thanks

2
Is MyServiceImpl annotated with @Transactional? Do you have <tx:annotation-driven/> in XML?Tomasz Nurkiewicz
thanks for the response, yes I have <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>jakstack

2 Answers

8
votes

If you have AspectJ-enabled transaction management (<tx:annotation-driven mode="aspectj" .../>) application of transactions happens in-place in the same class, either during build (compile-time weaving) or on startup (load-time weaving).

No new classes are created (like when using ) and no proxies (like with ordinary interface-based AOP in Spring). Instead bytecode of MyServiceImpl was modified directly without you even noticing. Unfortunately the only way to see AOP is to decompile your classes. If you use javap -c MyServiceImpl you'll find plenty of references to Spring transaction layer.

-3
votes

If you are using Spring MVC, make sure to scan specific controller classes alone in servlet context file. Otherwise it will scan 2 times and transaction is not available on the application context.