Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring transaction demarcation causes new Hibernate session despite use of OSIV
    text
    copied!<p>I'm using Hibernate with OpenSessionInViewInterceptor so that a single Hibernate session will be used for the entire HTTP request (or so I wish). The problem is that Spring-configured transaction boundaries are causing a new session to be created, so I'm running into the following problem (pseudocode):</p> <ul> <li>Start in method marked @Transactional(propagation = Propagation.SUPPORTS, readOnly = false)</li> <li>Hibernate session #1 starts</li> <li>Call DAO method to update object foo; foo gets loaded into session cache for session #1</li> <li>Call another method to update foo.bar, this one is marked @Transactional(propagation = Propagation.REQUIRED, readOnly = false) <ul> <li><strong>Transaction demarcation causes suspension of current transaction synchronization, which temporarily unbinds the current Hibernate session</strong></li> <li>Hibernate session #2 starts since there's no currently-existing session</li> <li>Update field bar on foo (loading foo into session cache #2); persist to DB</li> <li>Transaction completes and method returns, session #1 resumes</li> </ul></li> <li>Call yet another method to update another field on foo <ul> <li>Load foo from session cache #1, with <strong>old, incorrect value of bar</strong></li> <li>Update field foo.baz, persist foo to DB</li> <li>foo.bar's old value overwrites the change we made in the previous step</li> </ul></li> </ul> <p>Configuration looks like:</p> <pre><code>&lt;bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" autowire="byName"&gt; &lt;property name="flushModeName"&gt; &lt;value&gt;FLUSH_AUTO&lt;/value&gt; &lt;/property&gt; &lt;/bean&gt; &lt;bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt; &lt;property name="dataSource" ref="myDataSource" /&gt; &lt;/bean&gt; &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt; &lt;property name="useTransactionAwareDataSource" value="true" /&gt; &lt;property name="mappingLocations"&gt; &lt;list&gt; &lt;value&gt;/WEB-INF/xml/hibernate/content.hbm.xml&lt;/value&gt; &lt;/list&gt; &lt;/property&gt; &lt;property name="lobHandler"&gt; &lt;ref local="oracleLobHandler" /&gt; &lt;/property&gt; &lt;!--property name="entityInterceptor" ref="auditLogInterceptor" /--&gt; &lt;property name="hibernateProperties" ref="HibernateProperties" /&gt; &lt;property name="dataSource" ref="myDataSource" /&gt; &lt;/bean&gt; </code></pre> <p>I've done some debugging and figured out exactly where this is happening, here is the stack trace:</p> <pre><code>Daemon Thread [http-8080-1] (Suspended (entry into method doUnbindResource in TransactionSynchronizationManager)) TransactionSynchronizationManager.doUnbindResource(Object) line: 222 TransactionSynchronizationManager.unbindResource(Object) line: 200 SpringSessionSynchronization.suspend() line: 115 DataSourceTransactionManager(AbstractPlatformTransactionManager).doSuspendSynchronization() line: 620 DataSourceTransactionManager(AbstractPlatformTransactionManager).suspend(Object) line: 549 DataSourceTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 372 TransactionInterceptor(TransactionAspectSupport).createTransactionIfNecessary(TransactionAttribute, String) line: 263 TransactionInterceptor.invoke(MethodInvocation) line: 101 ReflectiveMethodInvocation.proceed() line: 171 JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 204 $Proxy14.changeVisibility(Long, ContentStatusVO, ContentAuditData) line: not available </code></pre> <p>I can't figure out why transaction boundaries (even "nested" ones - though here we're just moving from SUPPORTS to REQUIRED) would cause the Hibernate session to be suspended, even though OpenSessionInViewInterceptor is in use.</p> <p>When the session is unbound, I see the following in my logs:</p> <pre><code>[2010-02-16 18:20:59,150] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager Removed value [org.springframework.orm.hibernate3.SessionHolder@7def534e] for key [org.hibernate.impl.SessionFactoryImpl@693f23a2] from thread [http-8080-1] </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload