Search This Blog

Sunday, February 8, 2009

Websphere JTA Transaction Configuration For Hibernate/spring

Websphere JTA Transaction Configuration

We use Websphere 6.0 and Spring 2.5 with Hibernate 3.0. I was struggling with getting to use JTA Transaction working for this environment, and finally got it working.

For the versions above WebSphere Application Server V6.0.2.19 or V6.1.0.9 the declaration of the transaction manager can be done with the following.

for those who are less fortunate and stuck with older versions there are various suggestions to get it working. Some solutions are bit risky since some hibernate classes uses (eg: org.hibernate.transaction.WebSphereTransactionManagerLookup) undocumented internal classes in the websphere App Server.

The safer approach is to use org.hibernate.transaction.WebSphereExtendedJTATransactionLookup with JTA transactions. But this has limitations. It doesn't support PROPAGATION_NOT_SUPPORTED and PROPAGATION_REQUIRES_NEW transaction attributes.

see following urls for detailed explanations and options.
http://robertmaldon.blogspot.com/2006/09/using-websphere-transaction-manager.html
http://www-128.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html

I am listing down the solution worked for me here and the problems encountered.

The Spring configuration for transaction was declared as following.

transaction manager configuration
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="autodetectTransactionManager" value="false">
<property name="allowCustomIsolationLevels" value="true">
<property name="userTransactionName" value="java:comp/UserTransaction">
</bean>

<bean id="hibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.show_sql">true</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="jta.UserTransaction">java:comp/UserTransaction</prop >
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>

</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<list>
<value>classpath*:**/../../model/State.hbm.xml</value>
<value>classpath*:**/../../Title.hbm.xml</value>

</list>
</property>
<property name="hibernateProperties">
<ref bean="hibernateProperties">
</property>
<property name="dataSource">
<ref bean="dataSource">
</property>
</bean>

<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/jdbc/RRVTD</value></property>
</bean>


*When this is done application might return an error saying ...TransactionManager(websphere one) can't be assigned to
javax.transaction.UserTransaction.
It is a class loading problem: while spring loads the javax.TransactionManager interface definition from a jta.jar,
websphere loaded from an other one. Delete jta.jar from the classpath and it will work.*

No comments: