Issue Details (XML | Word | Printable)

Key: SPR-3210
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Juergen Hoeller
Reporter: ravindra chandak
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Spring Framework

Using HibernateInterceptor leads to IllegalStateException in case of a transaction timeout inside Weblogic

Created: 27/Feb/07 09:48 AM   Updated: 13/Oct/07 01:16 PM
Component/s: SpringDA
Affects Version/s: 1.2.5
Fix Version/s: 2.5 RC1

Time Tracking:
Not Specified

Environment: We use Spring(1.2.5) Hibernate(3.0.5),Weblogic(8.1) and Weblogic container managed transactions. All our server side requests get initiated through a Stateless EJB or an MDB

Virtual Machine: BEA JRockit JVM - 1.4.2
Platform: BEA WebLogic - 8.1


 Description  « Hide
Issue:
HibernateInterceptor throws the following exception when there is a transaction timeout inside Weblogic:
java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate3.SessionHolder@9 f7af3c] for key [org.hibernate.impl.SessionFactoryImpl@ae6e03a] bound to thread [ExecuteThread: '15' for queue: 'weblogic.kernel.Default']
at org.springframework.transaction.support.Transactio nSynchronizationManager.bindResource(Ljava.lang.Ob ject;Ljava.lang.ObjectV(TransactionSynchronizati onManager.java:156)
at org.springframework.orm.hibernate3.HibernateInterc eptor.invoke(Lorg.aopalliance.intercept.MethodInvo cationLjava.lang.Object;(HibernateInterceptor.ja va:90)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed()Ljava.lang.Object;(ReflectiveM ethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(Ljava.lang.Object;Ljava.lang.reflect.Met hod;[Ljava.lang.ObjectLjava.lang.Object;(JdkDynamicAo pProxy.java:174)

Cause:
In a case of a transaction timeout, Weblogic executes the rollback and transaction synchronization callbacks on a seperate thread. This causes an empty SessionHolder object to still be associated with the old thread. This in itself is not a problem and I see it is well documented in Spring's SpringSessionSynchronization class(method: beforeCompletion).

However, the problem is when the same thread is used for a new request in a non-transactional scope(EJB method with transaction NotSupported). When this happens,from what I understood by stepping through the SessionFactoryUtils.doGetSession method, Spring does not reuse the old SessionHolder attached to this reused thread. In other words, it does not put the new Session created into the already existing SessionHolder. This causes the SessionFactoryUtils.isSessionTransactional method to return false. Thus, HibernateInterceptor now tries to create a new Session Holder, and in the process throws the above mentioned exception.
This, however would work fine if the new request on this thread, would have started in a scope of a transaction.Then I see SessionFactoryUtils.registerJtaSynchronization puts this new Session in the old SessionHolder.

Proposed Solution:
Change the SessionFactoryUtils.doGetSession method to put the new Session in the old SessionHolder(if it exists), regardless of a request being in a JTA transaction or not.



 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Juergen Hoeller added a comment - 13/Oct/07 01:16 PM
This has finally been addressed for Spring 2.5 RC1.

Juergen