Announcement Announcement Module
Collapse
No announcement yet.
@Transactional annotation with Aspectj LTW Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @Transactional annotation with Aspectj LTW

    Hi,

    When using @Transactional annotation with LTW (Spring 2rc3 and Hibernate transaction manager)
    I am getting the following stack trace

    ** Exception 1 of 1 has message: null
    java.lang.NullPointerException
    at org.springframework.transaction.interceptor.Transa ctionAspectSupport.createTransactionIfNecessary(Tr ansactionAspectSupport.java:234)
    at org.springframework.transaction.aspectj.AbstractTr ansactionAspect.ajc$before$org_springframework_tra nsaction_aspectj_AbstractTransactionAspect$1$2a73e 96c(AbstractTransactionAspect.aj:64)
    at tv.cozmo.central.logic.peer.PeerHandler.createOrUp datePeer(PeerHandler.java)
    at tv.cozmo.central.logic.peer.PeerHandler$$FastClass ByCGLIB$$6f65dbef.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy. java:149)
    at org.springframework.aop.framework.Cglib2AopProxy$C glibMethodInvocation.invokeJoinpoint(Cglib2AopProx y.java:709)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :148)
    at org.springframework.transaction.interceptor.Transa ctionInterceptor.invoke(TransactionInterceptor.jav a:100)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :170)
    at org.springframework.aop.framework.Cglib2AopProxy$D ynamicAdvisedInterceptor.intercept(Cglib2AopProxy. java:647)
    at tv.cozmo.central.logic.peer.PeerHandler$$EnhancerB yCGLIB$$3a817d71.createOrUpdatePeer(<generated>)
    at tv.cozmo.central.web.controller.RegisterServlet.do Get_aroundBody0(RegisterServlet.java:33)
    at tv.cozmo.central.web.controller.RegisterServlet$Aj cClosure1.run(RegisterServlet.java:1)
    at org.aspectj.runtime.reflect.JoinPointImpl.proceed( JoinPointImpl.java:173)
    at tv.cozmo.central.logic.aop.PerServletAdvice.around AdviceTest(PerServletAdvice.java:41)
    at tv.cozmo.central.web.controller.RegisterServlet.do Get(RegisterServlet.java:1)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
    at org.springframework.web.servlet.handler.SimpleServ letHandlerAdapter.handle(SimpleServletHandlerAdapt er.java:63)
    at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:798)
    at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:728)
    at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:396)
    at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:350)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:252)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:178)
    at org.apache.catalina.authenticator.AuthenticatorBas e.invoke(AuthenticatorBase.java:432)
    at org.apache.catalina.valves.AccessLogValve.invoke(A ccessLogValve.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:868)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11 ConnectionHandler.processConnection(Http11BaseProt ocol.java:663)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.process Socket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThr ead.runIt(LeaderFollowerWorkerThread.java:80)
    at org.apache.tomcat.util.threads.ThreadPool$ControlR unnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Unknown Source)


    The Spring config looks as follows

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <tx:annotation-driven/>


    My guess (confirmed by some debugging) is that aspectj is "weaving around" (interceptor) bean that
    can't initialize some of its properties (transaction manager) outside the container.

    What is a correct/recommended way of using @Transactional annotation with aspectj LTW ?


    Thanks,

    Alex

  • #2
    Reproducable project will help

    It is possible to create and send a small project that exhibits this problem?

    -Ramnivas

    Comment


    • #3
      I am kind of busy right now, but I will try to build a small
      example over weekend.

      Thanks,

      Alex

      Comment


      • #4
        Hi Alex,

        as far as understand you want to use annotation on the objects that are not created by Spring (otherwise you need not AspectJ LTW). <tx:annotation-driven> serves only Spring beans and is of no use for you (more over, it may harm you if you try to use it parallel with LTW, I just recently posted it as bug).

        But it is documented how to achieve what you want; take a look on a snippet at the beginning of chapter 9.5.6 of Spring 2.0 RC3 Reference -

        Code:
        // configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods
        AnnotationTransactionAspect.aspectOf().setTransactionManager (txManager);
        Definitely, you need first to obtain this txManager - load as bean from Spring container or just create it if you work outside of Spring IoC container.

        BTW. one remark - I now play a lot with @Transactional and LTW and is quite unsatisfied, it seems to be very fragile and cumbersone and its behavior deviates a lot from behavior of the same annotation when used together with Spring beans and <tx:annotation-driven>. In my opinion (whatever it worth) it very far from production quality and have to be excluded from 2.0 final (or, at least, marked as "experimental" and not intended for production usage).

        Definitely, mileage of Spring development team may vary.

        Regards,

        Oleksandr Alesinskyy

        Comment


        • #5
          As I have just released you even need not include line
          Code:
          AnnotationTransactionAspect.aspectOf().setTransactionManager (txManager);
          mentioned in my previous post into your code, it's enough to include following bean definition into context

          Code:
          <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"
                      factory-method="aspectOf">
                  <property name="transactionManager" ref="txManager"/>
          </bean>
          Regards,

          Oleksandr Alesinskyy

          Comment


          • #6
            thanks

            Thanks a lot.

            It works fine the way you described, with or without redundant <tx:annotation-driven/> configuration.

            I have actually, implemented a version of @Transactional annotation with corresponding advice obtaining transaction manager outside of the Spring container. That one also works fine.
            I did not realize, as you have pointed out, that transaction manager can be set in AnnotationTransactionAspect itself ( as described in 9.5.6 ) .

            By the way, a case for using LTW to annotate methods in a Spring bean is when calling transaction-annotated method of a class from non-transactional method of the same class (that is without crossing container boundary). When Spring will support privileged aspects it will be possible to apply this to private methods as well.

            Regards,

            Alex

            Comment


            • #7
              When Spring will support privileged aspects it will be possible to apply this to private methods as well.

              For Spring it does not matter, if aspects are priviledged, just take source of
              AnnotationTransactionalAspect (distributed with Spring in aspectj directory) and modify whatever you wish. Distributed source, for reasons that are uncomprechesible for me supports only public methods (unlike <tx:annotation-driven> tag which supports as well defult and protected scopes).

              Just chaging in 2 pointcuts in this aspect "public" to "!private" expand make it (almost) consistent. For private you need to do slightly more, but it is absolutely doable.

              Comment


              • #8
                Thanks

                Thanks,

                Alex

                Comment

                Working...
                X