Существует Websphere AS 8.5, в котором работает XA Datasource. Также есть приложение Spring, которое должно работать в этой среде и подключаться к источнику данных. Контекст приложения загружается сервлетом, и приложение использует RmiExporters
для предоставления доступа RMI к некоторым службам (которые совместно используются в отдельном потоке), а все методы DAO отмечены @Transactional
.
Если я пытаюсь что-то записать в базу данных из основного потока (например, во время инициализации любого класса), это работает правильно. Но если я пытаюсь написать (или прочитать с помощью HQL SELECT-запроса) что-то через вызов RMI, я вижу исключение:
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.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getStatus(WebSphereExtendedJtaPlatform.java:119)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115)
at org.hibernate.service.jta.platform.internal.TransactionManagerBasedSynchronizationStrategy.canRegisterSynchronization(TransactionManagerBasedSynchronizationStrategy.java:56)
at org.hibernate.service.jta.platform.internal.AbstractJtaPlatform.canRegisterSynchronization(AbstractJtaPlatform.java:148)
at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.attemptToRegisterJtaSync(TransactionCoordinatorImpl.java:240)
at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.pulse(TransactionCoordinatorImpl.java:268)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1202)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:178)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:89)
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:179)
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:174)
at com.ibm.ws.jpa.management.JPAEMFactory.createEntityManager(JPAEMFactory.java:297)
at org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:202)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:211)
at com.sun.proxy.$Proxy414.persist(Unknown Source)
Реальная конфигурация следующая:
блок сохранения в файле persistence.xml:
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/oracledatasource</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="connection.pool.size" value="5" />
<property name="current_session_context_class" value="managed" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
</properties>
Конфигурация весны выглядит так:
<tx:jta-transaction-manager />
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
<property name="persistenceUnits">
<map>
<entry key="pu1" value="persistence/pu1" />
</map>
</property>
</bean>
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/pu1"/>
Что я могу попытаться исправить эту проблему?
java:comp/websphere/ExtendedJTATransaction
живет в потоке, которым управляет контейнер JavaEE (в данном случае Websphere), аRmiExpoter
живет в другом потоке, где нет контекста с такого рода транзакциями. Надеюсь пока хватит. - person darkled   schedule 24.06.2013