TransactionRequiredException Executing an update/delete query

239,274

Solution 1

I am not sure if this will help your situation (that is if it stills exists), however, after scouring the web for a similar issue.

I was creating a native query from a persistence EntityManager to perform an update.

Query query = entityManager.createNativeQuery(queryString);

I was receiving the following error:

caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query

Many solutions suggest adding @Transactional to your method. Just doing this did not change the error.

Some solutions suggest asking the EntityManager for a EntityTransaction so that you can call begin and commit yourself. This throws another error:

caused by: java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead

I then tried a method which most sites say is for use application managed entity managers and not container managed (which I believe Spring is) and that was joinTransaction().

Having @Transactional decorating the method and then calling joinTransaction() on EntityManager object just prior to calling query.executeUpdate() and my native query update worked.

I hope this helps someone else experiencing this issue.

Solution 2

In my case, I had the wrong @Transactional imported.

The correct one is:

import org.springframework.transaction.annotation.Transactional;

and not

import javax.transaction.Transactional;

Solution 3

I have also faced same issue when I work with Hibernate and Spring Jpa Data Repository. I forgot to place @Transactional on spring data repository method.

Its working for me after annotating with @Transactional.

Solution 4

as form the configuration xml it is clear that you are going to use spring based transaction. Please make sure that the import which you are using for @Transactional is "org.springframework.transaction.annotation.Transactional"

in your case it might be "javax.transaction.Transactional"

Solution 5

I received this exception when trying to run a bulk UPDATE query in a non-JTA (i.e. resource-local) entity manager in Java SE. I had simply forgotten to wrap my JPQL code in

em.getTransaction().begin();

and

em.getTransaction().commit();
Share:
239,274
user41498
Author by

user41498

Updated on July 08, 2022

Comments

  • user41498
    user41498 almost 2 years

    Hi I am using hibernate JPA with spring and mongodb and i am running my application on Glassfish-4.0.

    My service class is :

    @Component
    public class Test {
        @PersistenceContext
        EntityManager em;
        EntityManagerFactory emf;
    
        @Transactional
        public String persist(Details details) {
            details.getUsername();
            details.getPassword();
    
            Query query = em.createNativeQuery("db.details.find(username="+details.getUsername()+"&password="+details.getPassword());
    
            em.getTransaction().begin();
            em.persist(details);
            em.getTransaction().commit();
            em.flush();
            em.clear();
            em.close();
            query.executeUpdate();
            System.out.println("Sucessful!");
            return "persist";        
        }
    }
    

    And my spring-context.xml is :

    <?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:p="http://www.springframework.org/schema/p"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
        <context:component-scan base-package="com.javapapers.spring.mvc" />
        <context:annotation-config />
        <mvc:annotation-driven />
        <tx:annotation-driven transaction-manager="txManager" />
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/" />
            <property name="suffix" value=".jsp" />
        </bean>
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="ogmTest"/>
        </bean>
        <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        </bean>
    </beans>
    

    I have applied some changes in the code but their is no effect. Can anyone please help me to sort out this. Thanks in advance.

  • user41498
    user41498 over 9 years
    Hi @sanket thanks for the response i have tried your suggestion i am geting the same error.
  • DeepInJava
    DeepInJava over 9 years
    i have edited my solution. See above. Problem seems to be with your configuration file.
  • user41498
    user41498 over 9 years
    It worked without jpa Adapter by adding @Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) but it is not going to database. collection is not created at database
  • DeepInJava
    DeepInJava over 9 years
    i have missed bean "entityManagerFactory in my solution.i have edited my solution
  • user41498
    user41498 over 9 years
    If i use Jpa vendor adapter it show some errors so can you please specify me without jpa vendor adapter. Because here i am using mongodb
  • DeepInJava
    DeepInJava over 9 years
  • Michael Tontchev
    Michael Tontchev about 9 years
    For those reading this, to call joinTransaction you do em.joinTransaction(); (where em is your EntityManager object) (also, one of the spellings of the function in the answer above is bad, which is why you'll get the red squigglies in Eclipse if you just copy/paste. Instead, you can copy/paste the code in this comment here.)
  • sendon1982
    sendon1982 almost 9 years
    When I use "org.springframework.transaction.annotation.Transactional" it is working fine
  • Mark Miller
    Mark Miller about 7 years
    This helped me ... I needed both "@Transactional" and "@Modifying" on the JPA repository method. Just having this on my service method (which calls the JPA repository) did not seem to be enough.
  • 3xCh1_23
    3xCh1_23 over 6 years
    The edit did not add or improve the solution and therefore was not necessary. Thank you for (what you consider) an improved grammar. I would have preferred a more productive approach.
  • gene b.
    gene b. over 6 years
    THIS HELPED ME. @Transactional was required on the JPA DAO Repository method too! Unbelievable! You are a lifesaver, Satya P!!
  • Software Prophets
    Software Prophets almost 6 years
    Another thing to take note of is that package level visibility does not work on methods marked @Transactional. It must be public. As per this article: baeldung.com/transaction-configuration-with-jpa-and-spring, "Another caveat of using proxies is that only public methods should be annotated with Transactional – methods of any other visibilities will simply ignore the annotation silently as these are not proxied."
  • sinedsem
    sinedsem over 5 years
    Agreed, this is required if using @Modifing queries.
  • Cheloide
    Cheloide over 5 years
    This is an awful answer, you should be using prepared statemens for this. this code is vulnerable to injection attacks.
  • Shilan
    Shilan about 5 years
    with third solution i get this error: org.springframework.dao.InvalidDataAccessApiUsageException: No local transaction to join; nested exception is javax.persistence.TransactionRequiredException: No local transaction to join
  • Shilan
    Shilan about 5 years
    I used the factory instead and in each and every methoda I get the entityManager and handle the transaction manually with transaction.begin and commit() EntityManager entityManager = entityManagerFactory.createEntityManager();
  • sapy
    sapy about 5 years
    This works . import import org.springframework.transaction.annotation.Transactional; and add @Transactional to class level .
  • Danyal Sandeelo
    Danyal Sandeelo over 4 years
    This should be accepted as answer when when you are playing with native queries, you will need to do entityManager.joinTransaction();
  • HerTesla
    HerTesla over 4 years
    I was so blind! Thanks for this advice ... I just forgot the @Transactional annotation
  • Fisher Coder
    Fisher Coder about 4 years
    I don't know why either, I've tried to add '@Transactional' to all different methods, no luck, but once moved it to class level, the magic happens...
  • Gangnus
    Gangnus over 3 years
    Does not help for me - The only result is: java.lang.IllegalStateException: Not allowed to join transaction on shared EntityManager - use Spring transactions or EJB CMT instead. (I HAVE the Spring transaction)
  • michal.jakubeczy
    michal.jakubeczy almost 3 years
    have you add them to private methods? If so, @Transactional has no effect on them. In that case adding on class might help.
  • lewis machilika
    lewis machilika almost 3 years
    I am learning spring boot I have the same error but I don't know where you implement this solution below is my query. @Modifying @Query(nativeQuery = true, value = "update loan_application set transaction_status = :transaction_status where id =:id") void updateLoanApplicationStatus(@Param("transaction_status") int transaction_status,@Param("id") BigInteger id);
  • xbranko
    xbranko over 2 years
    I tried with both (one at a time) and it worked with either. Spring version used was 2.2.5.RELEASE. I left the spring one in code.