4
votes

I am facing an issue where I have one method which is calling another method in the service layer as follows:

@Transactional
    @Override
    public void method1(List<String> vals)
    {
        for (String value : vals){
            method2(value);
        }
    }

@Transactional(propagation= Propagation.REQUIRED)
public void method2(String value)
{
    //Hibernate Call 1

    //Hibernate Call 2

}

I have put the Transactional annotation in method 2 as it can be called from Controller also.

And my transaction manager looks like this:

<tx:annotation-driven transaction-manager="transactionManager"/>
<aop:aspectj-autoproxy/>

<!-- Transaction manager for hibernate -->

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="dataSource" ref="dataSource"></property>

</bean>

When I am running this code when the controller is calling method 1 it is giving the following error :

12/22/11 18:4455410: ERROR [ http-8181-1] (.support.TransactionSynchronizationUtils:87 ) - TransactionSynchronization.beforeCompletion threw exception java.lang.IllegalStateException: No value for key [org.hibernate.impl.SessionFactoryImpl@1b2668f] bound to thread [http-8181-1] at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:190) at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCompletion(SpringSessionSynchronization.java:187) at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCompletion(TransactionSynchronizationUtils.java:84) at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCompletion(AbstractPlatformTransactionManager.java:895) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:693) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy31.method1(Unknown Source)

1

1 Answers

1
votes

I can't see anything wrong with this code really. One thing you could try is a workaround: extract method2 code to another method, say method3 without @Transactional and call it from both method2 and method1 which stay @Transactional.

A side question: are method1 and method2 in the same class? If they are and JDK proxies are used then @Transactional around method2 will be ignored when called from method1.