TransactionRequiredException执行更新/删除查询

时间:2014-09-13 09:03:09

标签: java spring hibernate mongodb jpa

您好我正在使用带有spring和mongodb的hibernate JPA,我在Glassfish-4.0上运行我的应用程序。

我的服务类是:

@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";        
    }
}

我的spring-context.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: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>

我在代码中应用了一些更改,但它们没有效果。 任何人都可以帮我解决这个问题。 提前谢谢。

21 个答案:

答案 0 :(得分:46)

我不确定这是否会对您的情况有所帮助(即如果它仍然存在),但是,在网上搜索类似的问题之后。

我正在从持久性EntityManager创建本机查询以执行更新。

Query query = entityManager.createNativeQuery(queryString);

我收到以下错误:

  

由以下原因引起:javax.persistence.TransactionRequiredException:正在执行   更新/删除查询

许多解决方案建议在您的方法中添加@Transactional。 这样做并没有改变错误。

有些解决方案建议向EntityManager询问EntityTransaction,以便您可以自己调用begin和commit。 这引发了另一个错误:

  由引起的:java.lang.IllegalStateException:不允许创建   共享EntityManager上的事务 - 使用Spring事务或EJB   而不是CMT

然后我尝试了一种方法,大多数网站都说是使用应用程序管理的实体管理器而不是容器管理(我相信Spring是),那是joinTransaction()

@Transactional装饰方法然后在调用joinTransaction()之前调用EntityManager对象上的query.executeUpdate()并且我的本机查询更新有效。

我希望这有助于其他人遇到此问题。

答案 1 :(得分:24)

作为配置xml的形式,很明显你将使用基于spring的事务。请确保您用于@Transactional的导入是&#34; org.springframework.transaction.annotation.Transactional&#34;

在你的情况下,它可能是&#34; javax.transaction.Transactional&#34;

欢呼

Chetan Verma

答案 2 :(得分:21)

在我的情况下,我导入了错误的@Transaction。正确的是:

org.springframework.transaction.annotation.Transactional

javax.transaction.Transactional

答案 3 :(得分:10)

当我使用Hibernate和Spring Jpa Data Repository时,我也面临同样的问题。我忘了将@Transactional放在spring数据存储库方法上。

在使用@Transactional注释后,它为我工作。

答案 4 :(得分:4)

如何将@Transactional从方法级别移动到类级别? 在类似的情况下为我工作,虽然我不是100%肯定为什么。

答案 5 :(得分:4)

使用@Modifying和@Transaction修复了我

  1. @修改 @Query(value =“从WHERE user_id =?1”删除锁,nativeQuery = true) void deleteByUserId(Long userId);

  2. @服务 @Transactional

答案 6 :(得分:2)

我遇到了同样的错误。

我刚刚在方法上添加了 @Transactional 注释 javax.transaction.Transactional

答案 7 :(得分:2)

当我尝试在Java SE的非JTA(即资源本地)实体管理器中运行批量UPDATE查询时,收到此异常。 我只是忘记了将JPQL代码包装在

em.getTransaction().begin();

em.getTransaction().commit();

答案 8 :(得分:1)

在我意识到我的方法被声明为public final而不仅仅是public之前,似乎没有什么对我有用。该错误是由final关键字引起的。删除它会使错误消失。

答案 9 :(得分:1)

您无需担心开始和结束交易。您已经应用了@Transactional注释,它在您的方法开始时在内部打开事务,并在您的方法结束时结束。因此,只需将此对象保存在数据库中即可。

 @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";        
     }

编辑:问题似乎与您的配置文件有关。如果您使用的是JPA,那么您的配置文件应该具有以下配置

<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>

答案 10 :(得分:1)

只需在方法级别或类级别添加 @Transactional 。当您更新或删除记录时,必须保持Transaction的持久状态,@Transactional对此进行管理。

导入 org.springframework.transaction.annotation.Transactional;

答案 11 :(得分:1)

如下所示,将@PersistenceContext与@Modifying一起使用可修复使用createNativeQuery时的错误

    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.transaction.annotation.Transactional;

    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Transactional
    @Modifying
    public <S extends T> S save(S entity) {
         Query q = entityManager.createNativeQuery(...);
         q.setParameter...
         q.executeUpdate();
         return entity;
    }

答案 12 :(得分:0)

在某种不同的情况下,我发生了相同的例外。 由于我一直在这里寻找答案,因此也许会对某人有所帮助。

我的情况是发生了异常,因为我从 SERVICE CONSTRUCTOR ... 中调用了(正确注释的)@Transactional方法。 由于我的想法只是使该方法从一开始就运行,因此我将其注释为以下内容,并停止以错误的方式进行调用。异常消失了,代码更好了:)

@EventListener(ContextRefreshedEvent.class)
@Transactional
public void methodName() {...}

@事务导入:import org.springframework.transaction.annotation.Transactional;

答案 13 :(得分:0)

如果先前的答案失败,请确保对在存储库中调用update方法的类使用 @Service 构造型。我最初使用的是 @Component ,但是它不起作用,对@Service的简单更改使其可以工作。

答案 14 :(得分:0)

我在springboot项目中也遇到了这个问题,并在我的课程中添加了@Transactional,它正在工作。

import org.springframework.transaction.annotation.Transactional;
@Transactional
public class SearchRepo {
---
}

答案 15 :(得分:0)

运行代码时出现错误消息: javax.persistence.TransactionRequiredException:执行更新/删除查询

开始entityManager事务-> createNativeQuery->执行更新-> EntityManager事务提交以将其保存在数据库中。 Hibernate和postgresql对我来说很好用。

##代码##

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

答案 16 :(得分:0)

面对同样的问题,我只是忘记了使用@EnableTransactionManagement注释来激活事务管理。

参考:

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

答案 17 :(得分:0)

尽管在类级别添加@Transactional注释并导入org.springframework.transaction.annotation.Transactional,我仍然遇到相同的错误。

然后我意识到,由于我使用的是休眠查询,因此我导入了javax.persistence.Query而不是import org.hibernate.query.Query。 因此,添加了导入org.hibernate.query.Query。为我解决了这个问题。

我希望这个主意能对某人有所帮助。

答案 18 :(得分:0)

我遇到了同样的异常“ TransactionRequiredException执行更新/删除查询”但对我来说原因是我在spring中创建了另一个bean applicationContext.xml 名为“ transactionManager ”的文件引用“ org.springframework.jms.connection.JmsTransactionManage r”,但是有另一个同名的bean“ transactionManager < / strong>“引用” org.springframework.orm.jpa.JpaTransactionManager “。所以 JPA bean被 JMS bean压倒了。

重命名Jms的bean名称后,问题就解决了。

答案 19 :(得分:0)

在我的项目中将Spring 4与Hibernate 5集成并遇到此问题后,我发现通过更改会话从sessionFactory.openSession()sessionFactory.getCurrentSession()的方式,我可以防止出现错误。 解决这个错误的正确方法可能是继续使用相同的会话进行绑定事务。开始时,会始终创建一个新的会话,这个会话不像前者那样持有一个事务的configed.using getCurrentSession并添加其他属性<property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>的工作原理对我好。

答案 20 :(得分:-1)

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }