Environment:
WAS 8.0.0.2
Spring 3.1.1
Spring Integration 2.1.2
Hibernate: 4.1.4
We have a simple requirement that records from a staging table are polled using <si-jdbc:inbound-channel-adapter>, and after going through some SI endpoints through "direct channels", they will be persisted to DB2 tables using Hibernate.
Some relevant codes are posted here:
When the persistent code reaches Hibernate, we are getting following errors:Code:<bean id="txManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" /> <si-jdbc:inbound-channel-adapter query="select records" update="delete records" channel="stagingChannel" data-source="stagingDataSource"> <si:poller task-executor="wmTaskExecutor" max-messages-per-poll="1" fixed-delay="60000"> <si:transactional transaction-manager="txManager" propagation="REQUIRED" read-only="false" /> </si:poller> </si-jdbc:inbound-channel-adapter> <bean id="wmTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> <property name="workManagerName" value="wm/default" /> <property name="resourceRef" value="true" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> ... <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop> </props> </property> </bean>
We are thinking the reason is that the inbound-channel-adapter thread is spawned by Spring, even though it is using WAS WorkManager to poll the database record. The WAS worker thread, therefore, doesn't have many JEE container context propogated, thus the JNDI look up fails.Code:Caused by: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/websphere/ExtendedJTATransaction] at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJtaPlatform.java:156) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJtaPlatform.java:152) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124) at org.hibernate.context.internal.JTASessionContext.currentSession(JTASessionContext.java:86) at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:90) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041) Caused by: javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names. [Root exception is javax.naming.NameNotFoundException: Name comp/websphere not found in context "java:".]
We were thinking to change the Hibernate to 3.6.10, which then we can use LocalSessionFactoryBean.setJtaTransactionManager() to inject the UOW transactionManager to bypass the JNDI lookup, but it turns out that WebSphereUowTransactionManager.getTransactionManag er() always return NULL. Thus, Hibernate will use JDBC transaction.
Is there any workaround? Is it true that SI inbound-channel-adapter will most likely spawn application server unmanaged thread?
Thanks.


Reply With Quote
