Java Spring IllegalStateException:JTA EntityManager 不能使用 getTransaction()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24704870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:17:53  来源:igfitidea点击:

Spring IllegalStateException: A JTA EntityManager cannot use getTransaction()

javaspringwebsphere

提问by jaredready

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.

因此,在一个大型重构项目之后,我留下了这个异常并且不确定如何纠正它。它正在处理一些我没有编写的代码,我不熟悉它是如何工作的。还有其他问题处理这个异常,但似乎没有一个适合我的情况。

The class which uses EntityManageris SpecialClaimsCaseRepositoryImpl:

使用的类EntityManagerSpecialClaimsCaseRepositoryImpl

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:

持久性.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>

And here's my project structure:

这是我的项目结构:

enter image description here

在此处输入图片说明

>

>

Here's a portion of the stack trace, with the full trace at this fpaste

这是堆栈跟踪的一部分,在此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.

我在这里完全是个菜鸟,所以如果需要任何其他信息,请询问,我会更新。

Thanks for all the help!

感谢所有的帮助!

采纳答案by M. Deinum

The problem is your configuration. You have hibernate configured for JTA.

问题是你的配置。您已为 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)

You have 2 possible solutions

您有 2 种可能的解决方案

  1. remove the JpaTransactionManagerand replace it with a JTA transaction manager
  2. remove the remove the hibernate.transaction.manager_lookup_classfrom the hibernate settings.
  1. 删除JpaTransactionManager并用 JTA 事务管理器替换它
  2. hibernate.transaction.manager_lookup_class从休眠设置中删除。

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.

如果您真的不需要分布式事务选项 2 是最简单的,如果您需要分布式事务,只需添加即可<tx:jta-transaction-manager />为您的环境设置适当的 JTA tx 管理器。删除 的定义JpaTransactionManager

Update:

更新:

Your configuration is flawed in 2 ways.

您的配置有两个方面的缺陷。

  1. Your EntityManager configuration already contains a jndi lookup for the datasource, which you override in your applicationContext by configuring a local datasource
  2. You have both a <tx:jta-transaction-manager />and JpaTransactionManagerwhich one do you want to use? At the moment the latter is overriding the first one.
  1. 您的 EntityManager 配置已经包含对数据源的 jndi 查找,您可以通过配置本地数据源在 applicationContext 中覆盖该查找
  2. 你有一个<tx:jta-transaction-manager />JpaTransactionManager你想用哪一个?目前,后者覆盖了第一个。

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).

创建 2 个单独的配置,一个用于本地测试,另一个用于使用 JTA en JNDI 查找的生产。(最好你的测试代码只覆盖必要的 bean)。

回答by flob

Use WebSphereTransactionManagerLookupfor the transaction manager lookup in Hibernate

使用WebSphereTransactionManagerLookup在Hibernate的事务管理器查找

<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereTransactionManagerLookup" />

and remove your current transaction manager and replace it with the WebSphereUowTransactionManager.

并删除您当前的事务管理器并将其替换为WebSphereUowTransactionManager.

<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>

for your transaction manager lookup in Spring.

用于 Spring 中的事务管理器查找。

See IBM Websphereand Springdocs for more in depth documentation.

有关更深入的文档,请参阅 IBM WebsphereSpring文档。