I have a legacy code that use the TransactionManager to obtain access to the transaction to associate synchronization objects to the transaction afterCommit.
When I migrate to Spring 3, the recommended transaction manager to my solution is WebSphereUowTransactionManager, in truth, I feel that it is only a factory to the real Transaction Manager. But this transaction manager always return null in the method getTransactionManager().
I'm using EJB's 2.1 (legacy, remember?) with CMT.
My configuration is Spring 3.1.2.RELEASE, Hibernate 3.6.8.Final, Websphere 6.1.0.43, my beans are:
<bean
id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
<bean
name="auditContextManager"
class="... my class ...">
<property name="transactionManager">
<bean factory-bean="transactionManager" factory-method="getTransactionManager" />
</property>
</bean>
My hibernate configuration is:
<hibernate-configuration>
<session-factory>
<property name="hibernate.jdbc.fetch_size">200</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.bytecode.use_reflection_optimizer">true</property>
<property name="hibernate.connection.datasource">java:comp/env/jdbc/ORDS</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="hibernate.max_fetch_depth">3</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</property>
<property name="hibernate.show_sql">false</property>
... too much mappings to show here ...
</session-factory>
</hibernate-configuration>
And my bean auditContextManager has always transactionManager set to null.
It seems to me that WebSphereUowTransactionManager do not expose Transaction Manager intentionally. Is this alright ?
There is any way so I can get the Transaction Manager ? Since WebSphereUowTransactionManager is not really the transaction manager, but only a transaction manager factory.
It is not a factory for the TransactionManager but, as the name suggest, the UOWManager. It uses the Websphere native API for managing transactions (which has broader support for certain things than the plain JTA api).
So there isn't going to be a TransactionManager it will always be null.
Basically if you want the transactionamanager you will have to do a JNDI lookup.
com.ibm.ws.Transaction.TransactionManagerFactory is the factory you should use to get the transaction manager .
Related
We have implemented a spring message listener service and the main operation exposed by this service is multiple event driven database update.
The context looks like as below.
<bean id="consumerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="${jms.consumerContainer.concurrentconsumers}"/>
<property name="maxConcurrentConsumers" value="${jms.consumerContainer.maxconcurrentconsumers}"/>
<property name="errorHandler" ref="errorHandler" />
<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
<property name="destination" ref="listenerQueue" />
<property name="messageListener" ref="consumerContainer" />
<property name="receiveTimeout" value="10000" />
<property name="sessionTransacted" value="true" />
<property name="transactionManager" ref="txManager" />
</bean>
TX manager is hibernate.
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>
and annotated the concrete class with #Transactional.
We use Jboss application server support to integrate with MQ via jndi.
The problem here is if there are any exception at any layer in the listener, the overall transaction is not getting rolled back and the message does not move to back out queue. It's obvious that as we use Hibernate transaction manager, it's not aware of other resource like JMS transactions.
Can I replace this safely with JTA transaction as Jboss will handle overall transaction management? Is there any foreseen risk in doing so?
I believe its no longer needed to annotate the class with #Transactional if we are using JTA as below.
<bean id="jtatxManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
Thanks in advance.
Can I replace this safely with JTA transaction as Jboss will handle overall transaction management?
Yes, you can. You should just change your bean txManager definition.
I believe its no longer needed to annotate the class with #Transactional.
This is not true. You still need #Transactional. It allows spring to identify a transaction boundary.
I'm used to have persistence.xml in my projects in which I define the provider to use (hibernate in most cases).
However, I'm starting a new project in which it is mandatory to use Spring framework. I've seen some blogs describing the integration of Hibernate in Spring and I've understood that I should declare a session factory in spring's beans descriptor org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
All the examples I've seen don't mention the use of persistence.xml, persistence context, entity manager...
I'm not sure I understand this point, I always thought that Hibernate is just a provider of JPA unless the factory declared in application-context.xml is doing something in background. If it is the case, I would like to understand how it is working..
thanks in advance...
AnnotationSessionFactoryBean is Factory bean implemented by Spring to create Hibernate Session Factory and shared to Spring's Application Context.if you are planning to use Direct Hibernate ( in case you dont need persistent.xml / per-cont.xml / entityManager) you can provide the properties in AnnotationSession FactoryBean. and can be injected in Any DAO.
How ever if you are planing to wire through JPA. Then you need ( persistent and persistent-context and entity Manager). In order to do that you required three steps
1. declare / configure Spring's JPA Adapter to create EntityManager instance for you
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
Inside JPA Bean declaration provide details about your database and who is ORM provider such as ( hibernate /toplink / ....) in your case Hibernate
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle9Dialect"/>
</bean>
</property>
then Provide information about your persistent entity details in persistent.xml or some way
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
if you have any specific JPA properties then
<property name="jpaProperties">
<props>
<!-- <prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
-->
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
</props>
</property>
Bottom line, Spring provies adapters to directly to Hibernate ( in that case your dont need Jpa files such as persistent.xml and so but you need hibernate related files like hbm files) or adapters to the JPA ( in that case you have provide details about who is JPA vendor and instrut spring how to connect to the JPA vendor).
Hope the above clarifies.
We are upgrading our project from Spring 2.5.6 to 3.2.3 and Hibernate/JPA to 4.2.3.
In spring-ds.xml for transaction management we replaced original below config
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager">
<!-- This property is specifically required for JMS -->
<property name="transactionManager" ref="baseTransactionManager" />
</bean>
<bean id="baseTransactionManager"
class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean" />
<tx:annotation-driven transaction-manager="transactionManager" />
to below as WebSphereTransactionManagerFactoryBean class is superseded in latest WAS :
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
and JMS msg listener config looks like below :
<bean id="xxtMsgListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsxxConnectionFactory" />
<property name="destination" ref="jmsxxQueue" />
<property name="messageListener" ref="xxMessageListener" />
<property name="transactionManager" ref="transactionManager" />
<property name="taskExecutor" ref="taskExecutor" />
</bean>
With above config we are getting below error in WAS logs :
Setup of JMS message listener invoker failed for destination
queue://xxQueue?busName=zzBus' - trying to recover. Cause: No JTA UserTransactionavailable - programmatic PlatformTransactionManager.getTransaction usage not supported
Is there any other config/property required to upgrade to spring 3.2.3 ? or to config WebSphereUowTransactionManager do we need to set any property ?
In case you are using Hibernate in your application, the actual Hibernate version used can be the root cause of the problem.
We spent half a day debugging it (on a WebSphere box), and then found that indeed it was the hibernate version upgrade (from 4.2.7.Final to 4.2.12.Final) which caused issue, not the JMS configuration.
UPDATE: It seems that Hibernate includes transaction-api jboss-transaction-api_1.1_spec which was not compatible with the one present on Websphere. Simply excluding this from hibernate resolved the issue.
on the DefaultMessageListenerContainer, try setting the sessionTransacted property to true. this should enable transaction support with WebSphere
The error happens because you have used JTA transaction manager, while your connection factory is not XA capable. Essentially injected implementation of ConnectionFactory does not implement JTA interfaces. Thus transaction manager isn't able of enrolling a message consumption into a new instance of UserTransaction.
In other to fix this issues the one needs to use XA capable ConnectionFactory, or other non-jta transaction manager like Spring's JmsTransactionManager.
I am puzzled here. I wanted to implement optimistic locking in my spring hibernate program but the hibernate is not throwing StaleObjectStateException even though I open a data in separate browser and updated it separately.
My Dao looks like this:
public void update(User user) throws StaleObjectStateException{
sessionFactory.getCurrentSession().saveOrUpdate(user);
}
My Pojo look like this:
#Version#Temporal(TemporalType.TIMESTAMP)
#Column(name="timestamp", length=19)
public Timestamp getTimestamp() {
return this.timestamp;
}
Config.xml
<bean name="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<tx:annotation-driven />
<bean name="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
One of my doubt why it is NOT throwing exception is that upon update, the other session timestamp is also updated since the data is persisted? Please help.
Perry
I see that you are using spring transaction manager. So I suppose somewhere you have #Transactional annotation that tracks your transactions. In this case I think that StaleObjectStateExceptionwill be thrown not on execution of update method of you class but when the transaction will be commited. And I also think that spring will wrap hibernate exception into HibernateOptimisticLockingFailureException. So you need to add throws declaration to the method that marked with #Transactional annotation.
If you do not have any transactional annotation than you need to add some or use manual transaction handling in Dao.
I have the following config.
<bean id="abcManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AbcManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="xyzManager" ref="xyzManager"/>
</bean>
</property>
</bean>
<bean id="xyzManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.XyzManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="anotherManager" ref="anotherManager"/>
</bean>
</property>
</bean>
<bean id="anotherManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AnotherManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="oneMoreManager" ref="oneMoreManager"/>
</bean>
</property>
</bean>
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
We found that we get lots of weblogic connection releases when we have high load.
How is this related to the connection release issue?
We use Hibernate for DAO operations.
First, analyse the logs to see when spring creates and closes transactions.
Set the logger for org.springframework.transaction to DEBUG for this.
Next my guess is you need to examine your #Transactional annotations (which I assume you use on your managers (=services?). Make sure the propagation is set correctly because this might be related to your issue (hard to say without seeing your manager's code of course).
To answer your question directly:
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
Nothing, and no. I don't see anything wrong with this. Not sure what you mean about 'same DAO' - you don't have the same DAO. You have the same parent, but 3 distinct DAOs.
If you're asking, then, why is weblogic closing your DB connections before your transaction completes, we wouldn't be able to answer that with the information above.