Results 1 to 4 of 4

Thread: Problem when calling a transactionnal service inside a LTW aspect.

  1. #1
    Join Date
    Aug 2007
    Location
    Paris
    Posts
    25

    Default Problem when calling a transactionnal service inside a LTW aspect.

    Hi,

    I have transactions problems when I call services inside LTW aspects.
    Here is what I'm trying to do:

    Code:
    @Aspect
    public class MyAspect {
      
      @Autowired
      UserService userService;
    
      @AfterReturning(
      pointcut = "......."
        )
      public void f() {
          userService.list();   // Problem here No Hibernate Session bound to thread ....
      }
    
    }
    So I have an aspect "weaved" at load time (not managed by Spring).

    Inside f() I call a transactionnal service "userService.list()", the following exception is thrown :
    org.springframework.orm.hibernate3.HibernateSystem Exception: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here.
    I do not understand why this exception is thrown because when I use my service "userService.list()" outside the aspect it works. Transactions on "UserService.list()" are configure using <tx-advice> and works everywhere in the application.

    But it does not work inside the "MyAspect" LTW aspect, why ???
    Because "MyAspect" isn't managed by Spring ?

    Thanks.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    Your aspects are created before the other beans and are needed before proxying. So you are working with an unproxied/unadviced userService, whereas your other beans have a proxied instance. (I would expect to see some info/warn messages in your logfile if you would enable that loglevel).

    Instead of injecting your dependency lazy look it up. Make your aspect ApplicationContextAware and retrieve the bean from the context and then use it.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Aug 2007
    Location
    Paris
    Posts
    25

    Default

    Ok, thanks for your help, I've tried to do what you said.

    My code is the following:

    Code:
    @Aspect
    public class MyAspect implements ApplicationContextAware {
      
      private UserService userService;
      private static ApplicationContext applicationContext;
    
      @AfterReturning(
      pointcut = "......."
        )
      public void f() {
          this.getUserService().list();   // Problem here No Hibernate Session bound to thread ....
      }
    
      @Override
      public void setApplicationContext(ApplicationContext applicationContext)
          throws BeansException {
        this.applicationContext = applicationContext;
      }
    
      private UserService getUserService() {
        if(this.userService == null) {
          this.userService = (UserService)   this.applicationContext.getBean("userService ");
        }
        	
        return this.userService;
      }
    }
    But the hibernate exception is thrown again...
    In fact there is an other weird thing, I have multiple advices in my aspect.
    It appears that advices which are executed after transactionnal services (and use transactionnal services) does not throw this exception.
    But advices executed after functions like "f()" (not transactionnal) which use transactionnal services throw an hibernate exception indicating that the Hibernate Session is not bound to the current thread.

    Here is the detail of the exception trace I obtain after execution of an advice like "f()" (in this case UserService is replaced by ExecutionReportService) :
    DEBUG 2008-06-26 13:55:03,343 (AbstractMessageListenerContainer.java:577) - Initiating transaction rollback on application exception
    org.springframework.orm.hibernate3.HibernateSystem Exception: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SessionFactoryU tils.convertHibernateAccessException(SessionFactor yUtils.java:661)
    at org.springframework.orm.hibernate3.AbstractSession FactoryBean.convertHibernateAccessException(Abstra ctSessionFactoryBean.java:303)
    at org.springframework.orm.hibernate3.AbstractSession FactoryBean.translateExceptionIfPossible(AbstractS essionFactoryBean.java:282)
    at org.springframework.dao.support.ChainedPersistence ExceptionTranslator.translateExceptionIfPossible(C hainedPersistenceExceptionTranslator.java:62)
    at org.springframework.dao.support.DataAccessUtils.tr anslateIfNecessary(DataAccessUtils.java:212)
    at org.springframework.dao.support.PersistenceExcepti onTranslationInterceptor.invoke(PersistenceExcepti onTranslationInterceptor.java:146)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :171)
    at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy54.findRunning(Unknown Source)
    at com.mycompany.imp.server.services.workflow.deploye d.impl.ExecutionReportServiceImpl.findRunning(Exec utionReportServiceImpl.java:84)
    at com.mycompany.imp.server.services.workflow.aspects .WorkflowExecutionReportMaker.addJvmState(Workflow ExecutionReportMaker.java:194)
    at com.mycompany.imp.server.services.workflow.cpe.jms .server.impl.OnJvmStateListenerImpl.onJvmState(OnJ vmStateListenerImpl.java:106)
    at com.mycompany.imp.server.services.workflow.cpe.jms .server.impl.CpeInstanceMDP.executeOnJvmStateListe ners(CpeInstanceMDP.java:177)
    at com.mycompany.imp.server.services.workflow.cpe.jms .server.impl.CpeInstanceMDP.onJvmState(CpeInstance MDP.java:287)
    at com.mycompany.imp.server.services.workflow.cpe.jms .server.impl.CpeInstanceMDP.onMessage(CpeInstanceM DP.java:129)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doInvokeListener(AbstractMessageLi stenerContainer.java:531)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.invokeListener(AbstractMessageList enerContainer.java:466)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doExecuteListener(AbstractMessageL istenerContainer.java:435)
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.doReceiveAndExecute(Abstrac tPollingMessageListenerContainer.java:322)
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.receiveAndExecute(AbstractP ollingMessageListenerContainer.java:260)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.invokeL istener(DefaultMessageListenerContainer.java:944)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.run(Def aultMessageListenerContainer.java:868)
    at java.lang.Thread.run(Thread.java:619)
    Caused by: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionCo ntext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSe ssion(SessionFactoryImpl.java:544)
    at com.mycompany.imp.server.dao.hbm.AbstractHbmImpDao .createCriteria(AbstractHbmImpDao.java:93)
    at com.mycompany.imp.server.dao.hbm.AbstractHbmImpDao .createCriteria(AbstractHbmImpDao.java:134)
    at com.mycompany.imp.server.dao.workflow.hbm.HbmExecu tionReportDao.findRunning(HbmExecutionReportDao.ja va:82)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoi npointUsingReflection(AopUtils.java:310)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.invokeJoinpoint(ReflectiveMethodInvocat ion.java:182)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :149)
    at org.springframework.dao.support.PersistenceExcepti onTranslationInterceptor.invoke(PersistenceExcepti onTranslationInterceptor.java:138)
    ... 17 more
    So, do you know why this isn't working even with aspect class implementing ApplicationContextAware ?

    Thanks.

  4. #4
    Join Date
    Aug 2007
    Location
    Paris
    Posts
    25

    Default

    Hi, I have not found any solution to my problem, I think the problem is that I'm running an advice after a "not transactionnal" function.

    If it could help this is the code of the advice which does not works.

    Code:
    @AfterReturning(
            pointcut = "execution("
                + "void com.mycompany.imp.server.services.workflow.cpe.jms.server.impl.OnJvmStateListenerImpl.onJvmState(..))"
                + " && target(target) && args(jvmState,..)"
        )
        public void addJvmState(Object target, JvmState jvmState)
        {
            Validate.isNotNull(jvmState, "jvmState");
    
            OnJvmStateListenerImpl onJvmStateListener = (OnJvmStateListenerImpl) target;
    
            ExecutionReport executionReport = this.getExecutionReportService().findRunning(onJvmStateListener .getCpeInstanceManager().getDeployedUimaWorkflow());
                
    
            // -- Adds the new JvmState and updates the report
            executionReport.addExchangeMessage(new jvmStateMessage(jvmState));
    
            this.getExecutionReportService().update(executionReport);
        }
    
    private ExecutionReportService getExecutionReportService()
        {
            if (this.executionReportService == null)
            {
                this.executionReportService = (ExecutionReportService) applicationContext.getBean("executionReportService");
            }
    
            return this.executionReportService;
        }
    I think the problem could be:
    - "OnJvmStateListenerImpl()" is created with a new() (call to a constructor) and is not managed by Spring ??
    - the call to onJvmState() is done inside a Spring Message Driven Pojo, is this a problem ?? I don't remember how the Spring MDP container but perhaps this is the cause of "no hibernate session bound to thread" because the MDP container create new threads ?

    So is this could help to solve my problems ??

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •