没有可用于当前线程的实际事务的EntityManager - 无法可靠地处理“刷新”呼叫 [英] No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call

查看:184
本文介绍了没有可用于当前线程的实际事务的EntityManager - 无法可靠地处理“刷新”呼叫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些背景信息:我试图将一个大项目从Hibernate 3.6.8迁移到5.2.5(包括JPA升级2.0到2.1),Spring 3.2.3到4.3.5,并且面临严重的问题。到目前为止,Spring和Hibernate的配置没有改变,并且在旧版本上一直运行良好,但是升级问题我无法解决。


我得到的异常是:



  2017- 01-16 10:15:25,635 ERROR [[ACTIVE] ExecuteThread:'15'for队列:'weblogic.kernel.Default(self-tuning)'] org.myproject.common.messaging.BaseMDB:代码:(11702)Source :(通用)发生异常 - 在org.myproject.core.processing.message.MessageReceiverImpl中发生异常org.springframework.dao.InvalidDataAccessApiUsageException被捕获
org.springframework.dao.InvalidDataAccessApiUsageException:没有实际事务可用于当前线程的EntityManager - 不能可靠地处理冲洗呼叫;嵌套异常是javax.persistence.TransactionRequiredException:没有实际事务可用于当前线程的EntityManager - 无法可靠地处理'flush'调用
在org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
。在在org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
。在组织。 springframework.dao.support.PersistenceExceptionTranslati onInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(
at com.sun.proxy。$ Proxy187.flushAndClear(Unknown Source)
at org.myproject.core.BasePersistenceMDB.synchronizeBackend(BasePersistenceMDB.java:46)
at org.myproject.core.BasePersistenceMDB.onTextMessage(BasePersistenceMDB.java:32)
at org.myproject.common.messaging.BaseMDB.evaluateJMSMessage(BaseMDB.java:100)
at org.myproject.common .messaging.BaseMDB.onMessage(BaseMDB.java:51)
at sun.reflect.GeneratedMethodAccessor591.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
在在com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
。 java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:117)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support .DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core .repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at $ weblogic.ejb.container.internal.MDListener.execute上的
(MDListener.java:451)$ web
weblogic.ejb.container.internal。
at weblogic.ejb.container.internal。 MDListener.transactionalOnMessage(MDListener.java:375)
at weblogic.ejb.container.internal.TokenBasedJMSMessagePoller.processOneMessage(TokenBasedJMSMessagePoller.java:279)
at weblogic.ejb.container.internal.Token BasedJMSMessagePoller.run(TokenBasedJMSMessagePoller.java:121)
在weblogic.work.SelfTuningWorkManagerImpl $ WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:548)
在weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
导致:javax.persistence.TransactionRequiredException:没有实际事务可用于当前线程的EntityManager - 无法可靠地处理'flush'调用
at org.springframework.orm.jpa.SharedEntityManagerCreator $ SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:282)
at com.sun.proxy。$ Proxy163.flush(Unknown Source)
at org。 myproject.core.data.dao.impl.MyPersistenceContextImpl.flushAndClear(MyPersistenceContextImpl.java:49)
at sun.reflect.GeneratedMethodAccessor616.invoke(Unknown Source)
at sun.re flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:498)
在org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection( AopUtils.java:333)在org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190

在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 28 more

我的配置如下所示:
pom.xml(相关片段):

strong>

 <依赖项> 
< groupId> org.springframework< / groupId>
< artifactId> spring-context< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-context-support< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-core< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-jdbc< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-orm< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-tx< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-web< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-webmvc< / artifactId>
< version> 4.3.5.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-test< / artifactId>
< version> 4.3.5.RELEASE< / version>
< scope> test< / scope>
< /依赖关系>

用于Hibernate:

 < dependency> 
< groupId> org.hibernate.common< / groupId>
< artifactId> hibernate-commons-annotations< / artifactId>
< version> 5.0.1.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-core< / artifactId>
< version> 5.2.6.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-entitymanager< / artifactId>
< version> 5.2.6.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate.javax.persistence< / groupId>
< artifactId> hibernate-jpa-2.1-api< / artifactId>
< version> 1.0.0.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-jpamodelgen< / artifactId>
< version> 5.2.6.Final< / version>
< scope>提供< / scope>
< /依赖关系>

persistence.xml(full):但没有帮助:已添加jta-data-source,xsd版本已更新)

pre $ < persistence xmlns = http://xmlns.jcp.org/xml/ns/persistence
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation = http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd
version =2.1>

< persistence-unit name =MYPROJECT_PUtransaction-type =JTA>
< provider> org.hibernate.jpa.HibernatePersistenceProvider< / provider>
< jta-data-source> myproject-ds_jndi< / jta-data-source>

< mapping-file> META-INF / named-queries.xml< / mapping-file>

< class> org.myproj.core.domain.Message< / class>

< / persistence-unit>

< /持久性>

appContext.xml(相关片段):自升级以来,在jpaProperties中)

 <?xml version =1.0encoding =UTF-8?> 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns :context =http://www.springframework.org/schema/context
xmlns:tx =http://www.springframework.org/schema/txxmlns:jdbc =http:// www.springframework.org/schema/jdbc
xsi:schemaLocation =http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/ spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http ://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema / jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd\">

...

< bean
class =org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor/>

< bean
class =org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor/>

< bean
class =org.springframework.beans.factory.config.PropertyPlaceholderConfigurer>
< property name =locations>
< list>
< value> classpath:configuration.properties< / value>
< value> classpath:externalized-queries.properties< / value>
< / list>
< / property>
< / bean>

< bean id =jndiDataSourceclass =org.springframework.jndi.JndiObjectFactoryBean>
< property name =jndiNamevalue =$ {datasourceJndiName}>< / property>
< / bean>

<! - 表示Hibernate EntityManager的JpaVendorAdapter实现。 - >
< bean id =jpaVendorAdapter
class =org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter>
< property name =databasevalue =$ {databaseVendor}/>
< property name =showSqlvalue =$ {showSql}/>
< property name =generateDdlvalue =$ {generateDdl}/>
< property name =databasePlatformvalue =$ {databaseDialect}/>
< / bean>

< bean id =entityManagerFactory
class =org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean>
< property name =persistenceXmlLocationvalue =$ {persistenceXmlFileLocation}/>
< property name =persistenceUnitNamevalue =$ {persistenceUnitName}/>
< property name =dataSourceref =jndiDataSource/>
< property name =jpaVendorAdapterref =jpaVendorAdapter/>
< property name =jpaProperties>
<道具>
< prop key =hibernate.transaction.manager_lookup_class> $ {transactionManagerLookupClass}< / prop>
< prop key =hibernate.transaction.jta.platform> org.hibernate.service.jta.platform.internal.WebternalJtaPlatform< / prop> <! - 这是新添加的 - >

< /道具>
< / property>
< / bean>

< tx:annotation-driven />

< tx:jta-transaction-manager />

...

打开类的相关片段这个事务演示了在这里使用的注释:

  import java.sql.SQLException; 
import java.util.Set;

import javax.interceptor.Interceptors;

import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

...

@Interceptors(SpringBeanAutowiringInterceptor.class)
@Transactional(propagation = Propagation.REQUIRED)
public class DBLockingImpl implements Locking {

@Autowired
私有DataSource数据源;

这是调用entityManager的类(此时事务已经打开,但是当flush方法在EntityManager上被调用时会发生异常):

  import javax.persistence.EntityManager ; 
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository(value =persistenceContext)
public class PersistenceContextImpl
实现了PersistenceContext {

/ **
* EntityManager的实例变量。
* /
@PersistenceContext
私人EntityManager entityManager;

@Override
public void flushAndClear(){
entityManager.flush();
entityManager.clear();
}
}

那么有人可以帮我解决这个问题吗?我不明白什么是缺少的,为什么我得到这个例外。我得到的印象是,Spring没有正确地连接到Hibernates实体管理器,这就是异常的原因,因为trasanction本身似乎是创建的,但是每当它试图坚持这个异常时,它就会苍蝇。毕竟,我发现它不再适用,虽然它在这些框架的旧版本中运行良好。在旧版本的配置中是否有重大变化?

解决方案

扫描似乎有效。如果您查看堆栈跟踪,您可以看到EntityManager 代理(com.sun.proxy。$ Proxy163),并转发到 SharedEntityManagerCreator 按预期。然而,在创建SharedEntityManager之前,它会检查是否有事务,并且检查失败。交易应该由 @Transactional 注释创建。这通过Spring AOP发生,无论是创建一个扩展 DBLockingImpl 的GCLIB代理,还是一个实现锁定的JDK代理。这可以通过在方法中设置断点并查看callstack来查看方法的调用方式来确定。

查看 DBLockingImpl 我注意到您使用 SpringBeanAutowiringInterceptor 这表明DBLockingImpl不是一个Spring bean,但是你只需将Spring bean自动装入它。如果是这种情况,那么我认为这是你的问题,因为然后 DBLockingImpl 不会被AOP代理,因此@Transactional将不会被应用。



试着制作 DBLockingImpl 一个spring bean。


Some background info: I am trying to migrate a big project from Hibernate 3.6.8 to 5.2.5 (including JPA upgrade 2.0 to 2.1), Spring 3.2.3 to 4.3.5 and am facing serious issues. The configuration has not been changed for Spring and Hibernate so far and has been working fine on the old versions, however with the upgrade problems that I can't solve myself arose.

The exception I'm getting is:

2017-01-16 10:15:25,635 ERROR [[ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)'] org.myproject.common.messaging.BaseMDB: Code: (11702) Source: (Common) Exception caught - Exception org.springframework.dao.InvalidDataAccessApiUsageException in org.myproject.core.processing.message.MessageReceiverImpl caught
org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call
                at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
                at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
                at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
                at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
                at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
                at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
                at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
                at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
                at com.sun.proxy.$Proxy187.flushAndClear(Unknown Source)
                at org.myproject.core.BasePersistenceMDB.synchronizeBackend(BasePersistenceMDB.java:46)
                at org.myproject.core.BasePersistenceMDB.onTextMessage(BasePersistenceMDB.java:32)
                at org.myproject.common.messaging.BaseMDB.evaluateJMSMessage(BaseMDB.java:100)
                at org.myproject.common.messaging.BaseMDB.onMessage(BaseMDB.java:51)
                at sun.reflect.GeneratedMethodAccessor591.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
                at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
                at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
                at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
                at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:117)
                at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
                at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
                at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
                at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
                at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
                at com.sun.proxy.$Proxy121.onMessage(Unknown Source)
                at weblogic.ejb.container.internal.MDListener.execute(MDListener.java:451)
                at weblogic.ejb.container.internal.MDListener.transactionalOnMessage(MDListener.java:375)
                at weblogic.ejb.container.internal.TokenBasedJMSMessagePoller.processOneMessage(TokenBasedJMSMessagePoller.java:279)
                at weblogic.ejb.container.internal.TokenBasedJMSMessagePoller.run(TokenBasedJMSMessagePoller.java:121)
                at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:548)
                at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
                at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call
                at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:282)
                at com.sun.proxy.$Proxy163.flush(Unknown Source)
                at org.myproject.core.data.dao.impl.MyPersistenceContextImpl.flushAndClear(MyPersistenceContextImpl.java:49)
                at sun.reflect.GeneratedMethodAccessor616.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
                at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
                at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
                at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
                ... 28 more

My configuration looks as follows: pom.xml (relevant snippets): for Spring:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.5.RELEASE</version>
  </dependency>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.5.RELEASE</version>
    <scope>test</scope>
  </dependency>

for Hibernate:

<dependency>
        <groupId>org.hibernate.common</groupId>
        <artifactId>hibernate-commons-annotations</artifactId>
        <version>5.0.1.Final</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
       <version>5.2.6.Final</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.6.Final</version>
      </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.0.Final</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jpamodelgen</artifactId>
        <version>5.2.6.Final</version>
        <scope>provided</scope>
      </dependency>

persistence.xml (full): (here some things have been changed but didn't help: jta-data-source has been added, xsd versions have been updated)

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="MYPROJECT_PU" transaction-type="JTA">        
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>myproject-ds_jndi</jta-data-source>

        <mapping-file>META-INF/named-queries.xml</mapping-file>

        <class>org.myproj.core.domain.Message</class>

    </persistence-unit>

</persistence>

appContext.xml (relevant snippets): (just added one extra property in jpaProperties since the upgrade)

<?xml version="1.0" encoding="UTF-8"?>
<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" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">

...

<bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean
        class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:configuration.properties</value>
                <value>classpath:externalized-queries.properties</value>
            </list>
        </property>
    </bean>

    <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="${datasourceJndiName}"></property>
    </bean>

    <!-- Indicates a JpaVendorAdapter implementation for Hibernate EntityManager. -->
    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="${databaseVendor}" />
        <property name="showSql" value="${showSql}" />
        <property name="generateDdl" value="${generateDdl}" />
        <property name="databasePlatform" value="${databaseDialect}" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="${persistenceXmlFileLocation}" />
        <property name="persistenceUnitName" value="${persistenceUnitName}" />
        <property name="dataSource" ref="jndiDataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.transaction.manager_lookup_class">${transactionManagerLookupClass}</prop>
                <prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform</prop> <!-- this was newly added -->

            </props>
        </property>
    </bean>

    <tx:annotation-driven />

    <tx:jta-transaction-manager />

...

Relevant snippets from the class that opens the transaction demonstrating what annotations have been used here:

import java.sql.SQLException;
import java.util.Set;

import javax.interceptor.Interceptors;

import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

...

@Interceptors(SpringBeanAutowiringInterceptor.class)
@Transactional(propagation = Propagation.REQUIRED)
public class DBLockingImpl implements Locking {

@Autowired
private DataSource dataSource;

This is the class calling the entityManager (the transaction has already been opened at this point, but the exception happens when the flush method gets called on the EntityManager here):

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository(value = "persistenceContext")
public class PersistenceContextImpl
    implements PersistenceContext {

    /**
     * Instance variable for EntityManager.
     */
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void flushAndClear() {
        entityManager.flush();
        entityManager.clear();
    }
}

So can anybody please help me with this issue? I don't understand what's missing and why I am getting that exception. I get the impression that Spring is not connecting properly to Hibernates entity manager and that's why the exception comes, since the trasanction itself seems to be created, but whenever it tries to persist this exception flies. After all I find it weird that it is not working anymore, although it worked fine with the old versions of these frameworks. Have there been any big changes in configuration from the old versions?

解决方案

The scanning seems to work. If you look at the stacktrace you can see the EntityManager Proxy (com.sun.proxy.$Proxy163) and that it forwards toSharedEntityManagerCreatoras expected.

However, before creating the SharedEntityManager it checks if there is a transaction, and this check fails. The transaction should be created by the @Transactional annotation. This happens through Spring AOP, either creating a GCLIB proxy extendingDBLockingImplor a JDK Proxy implementing Locking. This can be determined by setting a breakpoint inside a method and looking at the callstack to see how the method was called.

Looking at DBLockingImpl I noticed that you use SpringBeanAutowiringInterceptorwhich suggests that DBLockingImpl is not a Spring bean, but you just autowire Spring beans into it. If this is that case then I think that is your problem, because then DBLockingImplwill not be AOP proxied, and the @Transactional will therefore not be applied.

Try making DBLockingImpla spring bean.

这篇关于没有可用于当前线程的实际事务的EntityManager - 无法可靠地处理“刷新”呼叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆