9

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

jakstack
  • 2,143
  • 3
  • 20
  • 37

2 Answers2

8

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.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    Thanks Tomasz, what you say makes sense so thanks for that. I de-compiled the class is this what you meant: AnnotationTransactionAspect.aspectOf().ajc$before$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(this, ajc$tjp_0); localJobSpec1 = (JobSpec)super.create(jobSpec); } catch (Throwable localThrowable) { AnnotationTransactionAspect.aspectOf().ajc$afterThrowing$org_springframework_transaction_aspectj_AbstractTransactionAspect$2$2a73e96c(this, localThrowable); throw localThrowable; } AnnotationTransactionAspect.aspectOf().ajc$after etc etc – jakstack Jul 14 '12 at 22:09
-4

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.

Junuxx
  • 14,011
  • 5
  • 41
  • 71
Anbarasan
  • 9
  • 1
  • 2
    Please stop posting the same copy/pasted answer everywhere. Try to ensure it is really relevant to the current question. – ForceMagic Oct 15 '12 at 06:51