[java] Spring - No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

I get this error when trying to invoke "persist" method to save entity model to database in my Spring MVC web application. Can't really find any post or page in internet that can relate to this particular error. It seems like something's wrong with EntityManagerFactory bean but i'm fairly new to Spring programming so for me it seems like everything is initialized fine and according to various tutorial articles in web.

dispatcher-servlet.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 http://www.springframework.org/schema/context 
  http://www.springframework.org/schema/context/spring-context-4.0.xsd
  http://www.springframework.org/schema/jdbc
  http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  http://www.springframework.org/schema/data/jpa
  http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
  http://www.springframework.org/schema/data/repository
  http://www.springframework.org/schema/data/repository/spring-repository-1.5.xsd
  http://www.springframework.org/schema/jee
  http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">

    <context:component-scan base-package="wymysl.Controllers" />
    <jpa:repositories base-package="wymysl.repositories"/> 
    <context:component-scan base-package="wymysl.beans" /> 
    <context:component-scan base-package="wymysl.Validators" /> 
    <bean
     class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
     <bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>

     <bean id="passwordValidator" class="wymysl.Validators.PasswordValidator"></bean>

     <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
        <property name="username" value="system" />
        <property name="password" value="polskabieda1" />
    </bean>

 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml" />
    <property name="dataSource" ref="dataSource" />

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
            <property name="showSql" value="true" />
            <property name="generateDdl" value="false" />
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.max_fetch_depth">3</prop>
            <prop key="hibernate.jdbc.fetch_size">50</prop>
            <prop key="hibernate.jdbc.batch_size">10</prop>
        </props>
    </property>
</bean>

    <mvc:annotation-driven />

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:messages" />
</bean>

    <bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
             <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

    <mvc:resources mapping="/resources/**" location="/resources/" />
    <mvc:resources mapping="/resources/*" location="/resources/css/"  
    cache-period="31556926"/>



</beans>

RegisterController.java

@Controller
public class RegisterController {

    @PersistenceContext
    EntityManager entityManager;

    @Autowired
    PasswordValidator passwordValidator;

    @InitBinder
    private void initBinder(WebDataBinder binder) {
        binder.setValidator(passwordValidator);
    }

    @RequestMapping(value = "/addUser", method = RequestMethod.GET)
    public String register(Person person) {


        return "register";

    }

    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public String register(@ModelAttribute("person") @Valid @Validated Person person, BindingResult result) {
        if(result.hasErrors()) {
            return "register";
        } else {
            entityManager.persist(person);
            return "index";

        }




    }

This question is related to java spring spring-mvc web-applications

The answer is


I had the same problem and I added tx:annotation-driven in applicationContext.xml and it worked.


I had the same error code when I used @Transaction on a wrong method/actionlevel.

methodWithANumberOfDatabaseActions() { 
   methodA( ...)
   methodA( ...)
}

@Transactional
void methodA( ...) {
  ... ERROR message
}

I had to place the @Transactional just above the method methodWithANumberOfDatabaseActions(), of course.

That solved the error message in my case.


For us, the problem came down to same context settings in multiple configuration files. Check you've not duplicated the following in multiple config files.

<context:property-placeholder location="classpath*:/module.properties"/>
<context:component-scan base-package="...." />

Just a note for other users searching for answers for thie error. Another common issue is:

You generally cannot call an @transactional method from within the same class.

(There are ways and means using AspectJ but refactoring will be way easier)

So you'll need a calling class and class that holds the @transactional methods.


Without @Transactional annotation you can achieve the same goal with finding the entity from the DB and then removing that entity you got from the DB.

CrudRepositor -> void delete(T var1);


I had the same error when accessing an already transactional-annotated method from a non-transactional method within the same component:

Before:
    @Component
    public class MarketObserver {
        @PersistenceContext(unitName = "maindb")
        private EntityManager em;

        @Transactional(value = "txMain", propagation = Propagation.REQUIRES_NEW)
        public void executeQuery() {
          em.persist(....);
        }


        @Async
        public void startObserving() {
          executeQuery(); //<-- Wrong
        }
    }

    //In another bean:
     marketObserver.startObserving();

I fixed the error by calling the executeQuery() on the self-referenced component:

Fixed version:
    @Component
    public class MarketObserver {
        @PersistenceContext(unitName = "maindb")
        private EntityManager em;

        @Autowired
        private GenericApplicationContext context;

        @Transactional(value = "txMain", propagation = Propagation.REQUIRES_NEW)
        public void executeQuery() {
          em.persist(....);
        }


        @Async
        public void startObserving() {
          context.getBean(MarketObserver.class).executeQuery(); //<-- Works
        }
    }

I had this issue for days and nothing I found anywhere online helped me, I'm posting my answer here in case it helps anyone else.

In my case, I was working on a microservice being called through remoting, and my @Transactional annotation at the service level was not being picked up by the remote proxy.

Adding a delegate class between the service and dao layers and marking the delegate method as transactional fixed this for me.


I got the same error when I executed the Spring JPA deleteAll() method from Junit test cases. I simply used the deleteInBatch() & deleteAllInBatch() and its perfectly works. We do not need to mark @Transactional at the test cases level.


boardRepo.deleteByBoardId(id);

Faced the same issue. GOT javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread

I resolved it by adding @Transactional annotation above the controller/service.


For anyone with the same issue as I had, I was calling a public method method1 from within another class. method1 then called another public method method2 within the same class. method2 was annotated with @Transactional, but method1 was not. All that method1 did was transform some arguments and directly call method2, so no DB operations here.

The issue got solved for me once I moved the @Transactional annotation to method1.

Not sure the reason for this, but this did it for me.


This helped us, maybe it can help others in the future. @Transaction was not working for us, but this did:

@ConditionalOnMissingClass("org.springframework.orm.jpa.JpaTransactionManager")


I removed the mode from

<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />

to make this work


Adding the org.springframework.transaction.annotation.Transactional annotation at the class level for the test class fixed the issue for me.


I got this exception while attempting to use a deleteBy custom method in the spring data repository. The operation was attempted from a JUnit test class.

The exception does not occur upon using the @Transactional annotation at the JUnit class level.


I had the same error because I switched from XML- to java-configuration.

The point was, I didn't migrate <tx:annotation-driven/> tag, as Stone Feng suggested.

So I just added @EnableTransactionManagement as suggested here Setting Up Annotation Driven Transactions in Spring in @Configuration Class, and it works now


This error had me foxed for three days, the situation I faced produced the same error. Following all the advice I could find, I played with the configuration but to no avail.

Eventually I found it, the difference, the Service I was executing was contained in a common jar, the issue turned out to be AspectJ not treating the Service instantiation the same. In effect the proxy was simply calling the underlying method without all the normal Spring magic being executed before the method call.

In the end the @Scope annotation placed on the service as per the example solved the issue:

@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
@Transactional
public class CoreServiceImpl implements CoreService {
    @PersistenceContext
    protected EntityManager entityManager;

    @Override
    public final <T extends AbstractEntity> int deleteAll(Class<T> clazz) {
        CriteriaDelete<T> criteriaDelete = entityManager.getCriteriaBuilder().createCriteriaDelete(clazz);
        criteriaDelete.from(clazz);
        return entityManager.createQuery(criteriaDelete).executeUpdate();
    }

}

The method I have posted is a delete method but the annotations affect all persistence methods in the same way.

I hope this post helps someone else who has struggled with the same issue when loading a service from a jar


If you have

@Transactional // Spring Transactional
class MyDao extends Dao {
}

and super-class

class Dao {
    public void save(Entity entity) { getEntityManager().merge(entity); }
}

and you call

@Autowired MyDao myDao;
myDao.save(entity);

you won't get a Spring TransactionInterceptor (that gives you a transaction).

This is what you need to do:

@Transactional 
class MyDao extends Dao {
    public void save(Entity entity) { super.save(entity); }
}

Unbelievable but true.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to spring

Are all Spring Framework Java Configuration injection examples buggy? Two Page Login with Spring Security 3.2.x Access blocked by CORS policy: Response to preflight request doesn't pass access control check Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Spring Data JPA findOne() change to Optional how to use this? After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName The type WebMvcConfigurerAdapter is deprecated No converter found capable of converting from type to type

Examples related to spring-mvc

Two Page Login with Spring Security 3.2.x ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized The type WebMvcConfigurerAdapter is deprecated RestClientException: Could not extract response. no suitable HttpMessageConverter found Spring boot: Unable to start embedded Tomcat servlet container UnsatisfiedDependencyException: Error creating bean with name 8080 port already taken issue when trying to redeploy project from Spring Tool Suite IDE Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed Difference between the annotations @GetMapping and @RequestMapping(method = RequestMethod.GET)

Examples related to web-applications

Spring - No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call How do I choose the URL for my Spring Boot webapp? Difference between MEAN.js and MEAN.io External VS2013 build error "error MSB4019: The imported project <path> was not found" How to unpackage and repackage a WAR file IntelliJ, can't start simple web application: Unable to ping server at localhost:1099 Using form input to access camera and immediately upload photos using web app Pass user defined environment variable to tomcat ASP.NET: HTTP Error 500.19 – Internal Server Error 0x8007000d Best practices when running Node.js with port 80 (Ubuntu / Linode)