'No EntityManager with actual transaction available for current thread - cannot reliably process 'flush' call

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?



Solution 1:[1]

I suspect that this can be an issue with your component scanning or package scanning. I cannot find the package scanning code in your spring configuration file. Please check that or update your configuration file.

Solution 2:[2]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Saket Puranik
Solution 2