Spring IllegalStateException:JTA EntityManager无法使用getTransaction() [英] Spring IllegalStateException: A JTA EntityManager cannot use getTransaction()
问题描述
因此,在一个大型重构项目之后,我留下了这个例外,并且不确定如何纠正它。它处理的是一些我没写过的代码,我不熟悉它是如何工作的。还有其他问题处理这个例外,但似乎没有一个问题适合我的情况。
So after a big refactoring project, I am left with this exception and am unsure as how to correct it. It's dealing with some code that I did not write and I am unfamiliar with how it all works. There are other questions out there dealing with this exception, but none seem to fit my situation.
使用 EntityManager的类
是 SpecialClaimsCaseRepositoryImpl
:
package com.redacted.sch.repository.jpa;
//Imports
@Repository
public class SpecialClaimsCaseRepositoryImpl extends SimpleJpaRepository<SpecialClaimsCaseDto, SpecialClaimsCaseDto.Id> implements SpecialClaimsCaseRepository{
@PersistenceContext(unitName = "schManager")
private EntityManager em;
//Some autogenerated methods
public void setEntityManager(EntityManager em) {
this.em = em;
}
public EntityManager getEntityManager() {
return em;
}
}
Persistence.xml:
Persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="schManager">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/SCH_DS</jta-data-source>
<class>com.redacted.sch.domain.model.SpecialClaimsCaseDto</class>
<properties>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.dialect" value="com.bcbsks.hibernate.dialect.DB2Dialect" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.generate_statistics" value="false" />
<property name="hibernate.jdbc.use_scrollable_resultset" value="true" />
</properties>
</persistence-unit>
</persistence>
sch_model_spring.xml:
sch_model_spring.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.redacted.repository.jpa,
com.redacted.sch.domain.model,
com.redacted.sch.repository.jpa,
com.redacted.sch.service,
com.redacted.sch.service.impl"/>
<tx:annotation-driven />
<tx:jta-transaction-manager />
<!-- Data source used for testing -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
<property name="url" value="jdbc:db2:redacted.redacted.com" />
<property name="username" value="redacted" />
<property name="password" value="redacted" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="schManager" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
这是我的项目结构:
>
这是堆栈跟踪的一部分,在此上有完整的跟踪fpaste
Here's a portion of the stack trace, with the full trace at this fpaste
Caused by: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:985)
at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:67)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
... 80 more
我在这里是一个总菜鸟,所以如果需要任何其他信息,请询问,我会更新。
I'm a total noob here, so if any other information is needed just ask and I'll update.
感谢所有帮助!
问题是你的配置。您已为JTA配置了休眠。
The problem is your configuration. You have hibernate configured for JTA.
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
您使用的是本地交易而非分布式交易。
Whereas you are using local transactions instead of distributed transactions.
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
您有2种可能的解决方案
You have 2 possible solutions
- 删除
JpaTransactionManager
并将其替换为JTA事务管理器 - 从hibernate设置中删除
hibernate.transaction.manager_lookup_class
。
- remove the
JpaTransactionManager
and replace it with a JTA transaction manager - remove the remove the
hibernate.transaction.manager_lookup_class
from the hibernate settings.
如果你真的不需要分布式交易,那么选项2是最简单的,如果你需要分布式交易,只需添加< tx:jta-transaction-manager />
将为您的环境设置合适的JTA tx管理器。删除 JpaTransactionManager
的定义。
If you don't really need distributed transactions option 2 is the easiest, if you need distributed transactions simply adding <tx:jta-transaction-manager />
will setup a proper JTA tx manager for your environment. Remove the definition for the JpaTransactionManager
.
更新:
您的配置有两种方式存在缺陷。
Your configuration is flawed in 2 ways.
- 您的EntityManager配置已包含数据源的jndi查找,您通过配置本地数据源在applicationContext中覆盖
- 您同时拥有
< tx:jta-transaction-manager />
和JpaTransactionManager
您要使用哪一个?目前后者正在覆盖第一个。
- Your EntityManager configuration already contains a jndi lookup for the datasource, which you override in your applicationContext by configuring a local datasource
- You have both a
<tx:jta-transaction-manager />
andJpaTransactionManager
which one do you want to use? At the moment the latter is overriding the first one.
创建2个单独的配置,一个用于本地测试,一个用于生产,使用JTA和JNDI查找。 (优选您的测试代码仅覆盖必要的bean)。
Create 2 seperate configurations one for local testing and one for production using JTA en JNDI lookups. (Preferable your testing code only overrides the beans necessary).
这篇关于Spring IllegalStateException:JTA EntityManager无法使用getTransaction()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!