更新到 Hibernate 5 后无法访问 TransactionManager 或 UserTransaction
Unable to access TransactionManager or UserTransaction after updating to Hibernate 5
我刚刚从 Hibernate 4.2.19 更新到 Hibernate 5.1.2。当然,这并不是说事情没有按计划进行。解决了几个问题后(其中JOIN FETCH不得不改成JOIN),现在运行进入下一个问题:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'idolConfig': Invocation of init method failed; nested exception is org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1575)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[...]
Caused by: org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.makePhysicalTransactionDelegate(JtaTransactionCoordinatorImpl.java:229)
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.getTransactionDriverControl(JtaTransactionCoordinatorImpl.java:203)
at org.hibernate.engine.transaction.internal.TransactionImpl.<init>(TransactionImpl.java:36)
at org.hibernate.internal.AbstractSessionImpl.getTransaction(AbstractSessionImpl.java:313)
at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:281)
at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1326)
at org.hibernate.jpa.internal.EntityManagerImpl.internalGetSession(EntityManagerImpl.java:133)
[...]
日志显示无法加载 JtaPlatform:
2016-11-14 15:34:22,853 DEBUG .o.j.EntityManagerFactoryUtils - Line {272} Opening JPA EntityManager
2016-11-14 15:34:22,973 DEBUG e.t.j.p.i.JtaPlatformInitiator - Line {42} No JtaPlatform was specified, checking resolver
2016-11-14 15:34:22,973 DEBUG e.t.j.p.i.JtaPlatformInitiator - Line {42} No JtaPlatform was specified, checking resolver
2016-11-14 15:34:22,974 DEBUG i.JtaPlatformResolverInitiator - Line {33} No JtaPlatformResolver was specified, using default [org.hibernate.engine.transaction.jta.platform.internal.StandardJtaPlatformResolver]
2016-11-14 15:34:22,974 DEBUG i.JtaPlatformResolverInitiator - Line {33} No JtaPlatformResolver was specified, using default [org.hibernate.engine.transaction.jta.platform.internal.StandardJtaPlatformResolver]
2016-11-14 15:34:22,992 DEBUG .i.StandardJtaPlatformResolver - Line {101} Could not resolve JtaPlatform, using default [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2016-11-14 15:34:22,992 DEBUG .i.StandardJtaPlatformResolver - Line {101} Could not resolve JtaPlatform, using default [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2016-11-14 15:34:22,994 DEBUG .JtaTransactionCoordinatorImpl - Line {258} JtaPlatform#retrieveTransactionManager returned null
2016-11-14 15:34:22,994 DEBUG .JtaTransactionCoordinatorImpl - Line {258} JtaPlatform#retrieveTransactionManager returned null
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {223} Unable to access TransactionManager, attempting to use UserTransaction instead
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {223} Unable to access TransactionManager, attempting to use UserTransaction instead
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {241} JtaPlatform#retrieveUserTransaction returned null
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {241} JtaPlatform#retrieveUserTransaction returned null
我没有 persistence.xml
文件。这是我的 spring.xml
:
<bean id="entityManagerFactoryEcli"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="commonUnit" />
<property name="dataSource" ref="dataSourceEcli" />
<property name="packagesToScan"
value="org.my.common.portal.domain,eu.cec.justice.common.domain.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.JTASessionContext</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.my.common.util.ECLICommonEhCacheRegionFactory</prop>
</props>
</property>
</bean>
<bean id="entityManagerFactoryCommon"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="portalUnit" />
<property name="dataSource" ref="dataSourceCommon" />
<property name="packagesToScan"
value="eu.cec.justice.common.domain.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.JTASessionContext</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.my.common.util.ECLICommonEhCacheRegionFactory</prop>
<prop key="hibernate.ejb.cfgfile">hibernate.cfg.xml</prop>
</props>
</property>
</bean>
<bean id="dataSourceCommon" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="$${portal.common.database.jndi}" />
<property name="resourceRef" value="true" />
</bean>
<bean id="dataSourceEcli" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="$${ecli.database.jndi}" />
<property name="resourceRef" value="true" />
</bean>
<tx:jta-transaction-manager />
<tx:annotation-driven/>
编辑:
将以下内容添加到 bean 属性并没有解决我的问题(我也降级到 Hibernate 5.0.0 但问题仍然存在):
<prop key="hibernate.transaction.coordinator_class">org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl</prop>
这也没有用:
<prop key="hibernate.transaction.coordinator_class">jta</prop>
这也删除了
<prop key="javax.persistence.transactionType">jta</prop>
但这也失败了。
三天的工作找出解决方案。向 spring.xml 添加了以下行:
<prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform</prop>
Hibernate 4.x 以某种方式能够自动识别,但现在您必须手动告诉它您正在使用哪个 JtaPlatform。
如 User Guide 中所述:
Hibernate tries to discover the JtaPlatform it should use through the
use of another service named
org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver
.
If that resolution does not work, or if you wish to provide a custom
implementation you will need to specify the
hibernate.transaction.jta.platform
setting.
尝试通过 hibernate.transaction.jta.platform
配置 属性.
提供底层 JTA 平台
我刚刚从 Hibernate 4.2.19 更新到 Hibernate 5.1.2。当然,这并不是说事情没有按计划进行。解决了几个问题后(其中JOIN FETCH不得不改成JOIN),现在运行进入下一个问题:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'idolConfig': Invocation of init method failed; nested exception is org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1575)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[...]
Caused by: org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.makePhysicalTransactionDelegate(JtaTransactionCoordinatorImpl.java:229)
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.getTransactionDriverControl(JtaTransactionCoordinatorImpl.java:203)
at org.hibernate.engine.transaction.internal.TransactionImpl.<init>(TransactionImpl.java:36)
at org.hibernate.internal.AbstractSessionImpl.getTransaction(AbstractSessionImpl.java:313)
at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:281)
at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1326)
at org.hibernate.jpa.internal.EntityManagerImpl.internalGetSession(EntityManagerImpl.java:133)
[...]
日志显示无法加载 JtaPlatform:
2016-11-14 15:34:22,853 DEBUG .o.j.EntityManagerFactoryUtils - Line {272} Opening JPA EntityManager
2016-11-14 15:34:22,973 DEBUG e.t.j.p.i.JtaPlatformInitiator - Line {42} No JtaPlatform was specified, checking resolver
2016-11-14 15:34:22,973 DEBUG e.t.j.p.i.JtaPlatformInitiator - Line {42} No JtaPlatform was specified, checking resolver
2016-11-14 15:34:22,974 DEBUG i.JtaPlatformResolverInitiator - Line {33} No JtaPlatformResolver was specified, using default [org.hibernate.engine.transaction.jta.platform.internal.StandardJtaPlatformResolver]
2016-11-14 15:34:22,974 DEBUG i.JtaPlatformResolverInitiator - Line {33} No JtaPlatformResolver was specified, using default [org.hibernate.engine.transaction.jta.platform.internal.StandardJtaPlatformResolver]
2016-11-14 15:34:22,992 DEBUG .i.StandardJtaPlatformResolver - Line {101} Could not resolve JtaPlatform, using default [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2016-11-14 15:34:22,992 DEBUG .i.StandardJtaPlatformResolver - Line {101} Could not resolve JtaPlatform, using default [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2016-11-14 15:34:22,994 DEBUG .JtaTransactionCoordinatorImpl - Line {258} JtaPlatform#retrieveTransactionManager returned null
2016-11-14 15:34:22,994 DEBUG .JtaTransactionCoordinatorImpl - Line {258} JtaPlatform#retrieveTransactionManager returned null
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {223} Unable to access TransactionManager, attempting to use UserTransaction instead
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {223} Unable to access TransactionManager, attempting to use UserTransaction instead
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {241} JtaPlatform#retrieveUserTransaction returned null
2016-11-14 15:34:22,995 DEBUG .JtaTransactionCoordinatorImpl - Line {241} JtaPlatform#retrieveUserTransaction returned null
我没有 persistence.xml
文件。这是我的 spring.xml
:
<bean id="entityManagerFactoryEcli"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="commonUnit" />
<property name="dataSource" ref="dataSourceEcli" />
<property name="packagesToScan"
value="org.my.common.portal.domain,eu.cec.justice.common.domain.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.JTASessionContext</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.my.common.util.ECLICommonEhCacheRegionFactory</prop>
</props>
</property>
</bean>
<bean id="entityManagerFactoryCommon"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="portalUnit" />
<property name="dataSource" ref="dataSourceCommon" />
<property name="packagesToScan"
value="eu.cec.justice.common.domain.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.JTASessionContext</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.my.common.util.ECLICommonEhCacheRegionFactory</prop>
<prop key="hibernate.ejb.cfgfile">hibernate.cfg.xml</prop>
</props>
</property>
</bean>
<bean id="dataSourceCommon" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="$${portal.common.database.jndi}" />
<property name="resourceRef" value="true" />
</bean>
<bean id="dataSourceEcli" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="$${ecli.database.jndi}" />
<property name="resourceRef" value="true" />
</bean>
<tx:jta-transaction-manager />
<tx:annotation-driven/>
编辑:
将以下内容添加到 bean 属性并没有解决我的问题(我也降级到 Hibernate 5.0.0 但问题仍然存在):
<prop key="hibernate.transaction.coordinator_class">org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl</prop>
这也没有用:
<prop key="hibernate.transaction.coordinator_class">jta</prop>
这也删除了
<prop key="javax.persistence.transactionType">jta</prop>
但这也失败了。
三天的工作找出解决方案。向 spring.xml 添加了以下行:
<prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform</prop>
Hibernate 4.x 以某种方式能够自动识别,但现在您必须手动告诉它您正在使用哪个 JtaPlatform。
如 User Guide 中所述:
Hibernate tries to discover the JtaPlatform it should use through the use of another service named
org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver
.If that resolution does not work, or if you wish to provide a custom implementation you will need to specify the
hibernate.transaction.jta.platform
setting.
尝试通过 hibernate.transaction.jta.platform
配置 属性.