TransactionRequiredException Executing an update/delete query

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.

Answers


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.


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"

cheers

Chetan Verma


In my case I had the wrong @Transaction imported. The correct one is:

org.springframework.transaction.annotation.Transactional

and not javax.transaction.Transactional.


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 annotation the with @Transactional.


How about moving @Transactional from method to class level? Worked for me in similar case, though I'm not 100% certain why.


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();

Just add @Transactional on method level or class level. When you are updating or deleting record/s you have to maintain persistence state of Transaction and @Transactional manages this.

and import org.springframework.transaction.annotation.Transactional;


I Got the same error.

I just added the @Transactional annotation of javax.transaction.Transactional on the method.


You need not to worry about begin and end transaction. You have already apply @Transactional annotation, which internally open transaction when your method starts and ends when your method ends. So only required this is to persist your object in database.

 @Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})

         public String persist(Details details){
             details.getUsername();
             details.getPassword();
             Query query = em.createNativeQuery("db.details.find(username= "+details.getUsername()+"& password= "+details.getPassword());

             em.persist(details);
             System.out.println("Sucessful!");
            return "persist";        
     }

EDIT : The problem seems to be with your configuration file. If you are using JPA then your configuration file should have below configuration

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
    p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="jpaAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="ORACLE" p:showSql="true" />
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:persistenceUnitName="YourProjectPU"
    p:persistenceXmlLocation="classpath*:persistence.xml"
    p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
    <property name="loadTimeWeaver">
        <bean
            class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
    <property name="persistenceProvider" ref="interceptorPersistenceProvider" />

</bean>

Nothing seemed to work for me until I realized that my method was declared as public final instead of just public. The error was being caused by the final keyword. Removing it made the error go away.


After integrating Spring 4 with Hibernate 5 in my project and experiencing this problem, I found that I could prevent the error from appearing by changing the way of getting the session from sessionFactory.openSession() to sessionFactory.getCurrentSession(). the proper way to work out this bug may be keep using the same session for the binding transaction.opensession will always create a new session which doesnt like the former one holding a transaction configed.using getCurrentSession and adding additional property <property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property> works fine for me.


I faced the same exception "TransactionRequiredException Executing an update/delete query" but for me the reason was that I've created another bean in the spring applicationContext.xml file with the name "transactionManager" refering to "org.springframework.jms.connection.JmsTransactionManager" however there was another bean with the same name "transactionManager" refering to "org.springframework.orm.jpa.JpaTransactionManager". So the JPA bean is overriten by the JMS bean.

After renaming the bean name of the Jms, issue is resolved.


I was facing the same error inspite of adding @Transactional annotation at class level and importing org.springframework.transaction.annotation.Transactional.

Then I realized that since I was using hibernate query, I had imported javax.persistence.Query instead of import org.hibernate.query.Query. Therefore adding import org.hibernate.query.Query. solved the issue for me.

I hope this idea helps someone.


Faced the same problem, I simply forgot to activate the transaction management with the @EnableTransactionManagement annotation.

Ref:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html


Error message while running the code:

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

Begin the entityManager transaction -> createNativeQuery -> execute update -> entityManager transaction commit to save it in your database. It is working fine for me with Hibernate and postgresql.

Code

entityManager.getTransaction().begin();
Query query = entityManager.createNativeQuery("UPDATE tunable_property SET tunable_property_value = :tunable_property_value WHERE tunable_property_name = :tunable_property_name");
query.setParameter("tunable_property_name", tunablePropertyEnum.eEnableJobManager.getName());
query.setParameter("tunable_property_value", tunable_property_value);
query.executeUpdate();
entityManager.getTransaction().commit();

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;


    @Transactional
    public int changepassword(String password, long mobile) {
        // TODO Auto-generated method stub
        session = factory.getCurrentSession();
        Query query = session.createQuery("update User u set u.password='" + password + "' where u.mobile=" + mobile);
        int result = query.executeUpdate();

        return result;
    }
add this code 200% it will work... might scenario is diff but write like this:)

Need Your Help

heroku - how to see all the logs

heroku logging

I have a small app on heroku. Whenever I want to see the logs I go to the command line and do