背景情報:大きなプロジェクトをHibernate 3.6.8から5.2.5に移行しようとしています(JPAアップグレード2.0から2.1を含む)。 3.2.3から4.3.5の春にかけて、深刻な問題に直面しています。これまでSpringとHibernateの設定は変更されておらず、古いバージョンではうまくいきましたが、自分では解決できないアップグレードの問題が発生しました。現在のスレッドで実際のトランザクションが利用できるEntityManagerがない - 'flush'コールを確実に処理できない
私は取得しています例外は次のとおりです。
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
私の設定は次のようになります。 のpom.xml(関連スニペット):春のため :
<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 Hibe rnate:
<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(フル):(ここではいくつかの点が変更されましたが、助けにはならなかった:JTAデータ・ソースが追加されている、XSDのバージョンが更新されている)
<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(関連スニペット):(ちょうどアップグレード以来jpaPropertiesに1つの余分プロパティを追加しました)
<?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 />
...
注釈がここで使用されているかどうかを実証するトランザクションを開き、クラスからの
関連スニペット:
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;
これは、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
implements PersistenceContext {
/**
* Instance variable for EntityManager.
*/
@PersistenceContext
private EntityManager entityManager;
@Override
public void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
}
だから、誰もがこの問題で私を助けてくださいことができますか?私は何が欠けているのか、なぜその例外を受けているのか理解していません。私は、SpringがHibernateエンティティマネージャに正しく接続していないという印象を受けます。なぜなら、その例外は、それ自体が作成されているように見えますが、この例外を保持しようとするたびに発生します。結局のところ、このフレームワークの古いバージョンではうまくいきましたが、それはもう機能していないというのは変です。古いバージョンの設定に大きな変更がありましたか?
私は '' 'PersistenceContextImpl'''クラスに困惑していますが、なぜPersistenceContextアノテーションをオーバーライドしますか? Springでは、注入されたEntityManagerはTransactionalおよびThreadLocalストレージと対話するプロキシであり、Transactionalアノテーションが尊重されていないのとほとんど同じです。他の誰かがこれを前に試して、その原因を知っていれば、あなたは非常に幸運になると思います。私はあなたがこれを理解するためにデバッグする必要があることを恐れています。 –
プロジェクトを既にアップグレードしている場合、Mavenと膨大なXML設定を取り除いてGradleに切り替えることはできません;) –
@KlausGroenbaekここで混乱して申し訳ありませんが、PersistenceContextImplはこのケースではPersistenceContextアノテーションですが、使用され、データベースとのやりとりがある通常のクラスです。 Gradleについての情報をありがとうございます;)私は将来Gradleをチェックしますが、MavenからGradleへの移行はかなり致命的であると確信しています:D – ProgEngineer