Thursday, September 21, 2006

Using the WebSphere transaction manager with Spring and Hibernate

It is surprising that there is almost no documentation on how to integrate the common Spring/Hibernate combination with WebSphere's transaction manager. (The Hibernate forums berate IBM for not providing info on WebSpere JTA hooks, and you have to crawl through some of the Spring code to find the correct classes to use.)

For simple applications that only hit a single database you can probably get away with using Hibernate's default simulated transactions, but if your app has to talk to multiple transactional resources (good ol XA) then it's a good idea to hook into WebSphere's transaction manager.

Without further suspense here is how you do it:

First, use the highlighted Hibernate properties when defining the Spring session factory:


<bean id="petStoreSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
</bean>


If you are using Spring 2.1 RC1 or later then define a transaction manager using the WebSphereUowTransactionManager bean:


<bean id="wsJtaTm" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>


For earlier versions of Spring that do not provide org.springframework.transaction.jta.WebSphereUowTransactionManager, and for versions of WebSphere earlier than V6.0.2.19 or V6.1.0.9 that do not provide com.ibm.wsspi.uow.UOWManager, transaction support in WebSphere is available by using a basic Spring transaction management bean :


<bean id="wsJtaTm" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="autodetectTransactionManager" value="false"/>
</bean>



This configuration supports a restricted set of transaction attributes that does not include PROPAGATION_NOT_SUPPORTED and PROPAGATION_REQUIRES_NEW. The Spring class org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean, which also claims to provide PROPAGATION_NOT_SUPPORTED and PROPAGATION_REQUIRES_NEW capabilities, uses unsupported internal WebSphere interfaces and should not be used.

And finally when you define a TransactionInterceptor or TransactionProxyFactoryBean make sure to use the WebSphereTransactionManagerFactoryBean with the JtaTransactionManager :


<bean id="petStoreTransactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<bean class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="wsJtaTm"/>
</bean>
</property>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</property>
</bean>


And that's it. As my old colleague Stuart Cooper likes to say: "MMMaaagggiiiccc!!!"

Update: The article "Using Spring and Hibernate with WebSphere Application Server" highlights some Spring 2.0 specific integration issues, such as transaction isolation levels and threads.

10 comments:

srinivas c said...

Well, the configuration only works as long as you don't start a new transaction or suspend one and start a new. just FYI

Srini

Robert Maldon said...

Thanks for the info. Do you have any suggested changes to make new/suspend work?

Neo said...

Hi Robert,

Do u know how to configure transaction with Jsf-Spring-ibatis.Currently im facing a problem in Jsf-Spring-ibatis with WAS 6.0 in RAD

Robert Maldon said...

Hi Neo,

I haven't had the opportunity to run as JSF/Spring/iBatis stack. If the Spring dudes did a complete integration (they usually do) then I would assume you should just have to wire together the WAS 6.0 transaction management as described above.

The only thing I can think to check is to make sure you are running in WAS 6.0.2.19 or later and using the WebSphereUowTransactionManager class.

Anonymous said...

I think it can be done in simpler fashion than that...

<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>

<bean id="petStoreSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
 <property name="hibernateProperties">
  <props>
  <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
  <prop key="hibernate.show_sql">false</prop>
  <prop key="hibernate.transaction.flush_before_completion">true</prop>
  <prop key="hibernate.transaction.auto_close_session">true</prop>
  <prop key="hibernate.cache.use_query_cache">false</prop>
  <prop key="hibernate.cache.use_second_level_cache">false</prop>
  </props>
 </property>
</bean>
Due to its bean name, Spring will auto inject the transactionManager into the LocalSessionFactoryBean.

This means you aren't trying to double configure the transaction manager.

Robert Maldon said...

Thanks Anonymous, your version is more compact. I think I prefer to explicitly set the TM rather than rely on auto-wiring magic - just in case :)

Anonymous said...

I get this error , I use Spring 2.5 and websphere 6.o can you please let me know the problem?

Anonymous said...

I mean this error

java.lang.NoClassDefFoundError: com.ibm.wsspi.uow.UOWAction

Robert Maldon said...

What is the full version of WAS6.0 you are using? I understand the UOW stuff is available from version 6.0.2.19 and later.

Blogger said...

Are you trying to make cash from your websites/blogs with popunder advertisments?
In case you do, have you considered using Ero Advertising?