Hibernate: Supporting Spring DataSourceTransactionManager (and @Transactional) programmatically with SessionFactoryUtils
Sunday, July 5th, 2009Here is the minimum code to support DataSourceTransactionManager thread bound session (similar to OpenSessionInViewInterceptor).
For each thread:
public void beginThreadSession(SessionFactory sessionFactory){
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
}
public void endThreadSession(SessionFactory sessionFactory){
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSession(sessionHolder.getSession());
}
DataSourceTransactionManager will pickup the thread bound session with SessionFactoryUtils. The trick is calling the “un/bindResource” methods. This set one session for all your requests and transactions for a given thread (and use the @transactional if you have configured it as follow).
<aop:config proxy-target-class="true"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="configLocation" value="config/hibernate.cfg.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Obviously, this is the strict minimum code (good of unit testing for example). For Web App, use the OpenSessionInViewInterceptor.
<bean id="openSessionInView"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory"/>
<!-- optional
<property name="flushModeName" value="FLUSH_NEVER" />
-->
</bean>