Java TransactionRequiredException执行更新/删除查询

Java TransactionRequiredException执行更新/删除查询,java,spring,hibernate,mongodb,jpa,Java,Spring,Hibernate,Mongodb,Jpa,您好,我正在spring和mongodb中使用HibernateJPA,我正在Glassfish-4.0上运行我的应用程序 我的服务级别是: @Component public class Test { @PersistenceContext EntityManager em; EntityManagerFactory emf; @Transactional public String persist(Details details) {

您好,我正在spring和mongodb中使用HibernateJPA,我正在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>

我在代码中应用了一些更改,但它们没有效果。 谁能帮我把这件事弄清楚吗。
提前感谢。

您不必担心开始和结束事务。您已经应用了@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>

我不确定这是否会对你的情况有所帮助(也就是说,如果它仍然存在的话),但是,在浏览网页寻找类似的问题之后

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

Query query = entityManager.createNativeQuery(queryString);
我收到以下错误:

原因:javax.persistence.TransactionRequiredException:正在执行 更新/删除查询

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

一些解决方案建议向EntityManager请求
EntityTransaction
,以便您可以调用begin并提交自己。 这会引发另一个错误:

原因:java.lang.IllegalStateException:不允许创建 共享EntityManager上的事务-使用Spring事务或EJB 改为CMT

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

@Transactional
修饰方法,然后在调用
query.executeUpdate()
之前在EntityManager对象上调用
joinTransaction()
,我的本机查询更新工作正常


我希望这能帮助其他遇到此问题的人。

作为配置xml的一部分,很明显您将使用基于spring的事务。请确保用于@Transactional的导入是“org.springframework.transaction.annotation.Transactional”


在您的例子中,它可能是“javax.transaction.Transactional”

直到我意识到我的方法被声明为
public final
,而不是
public
,我才觉得什么都不管用。错误是由
final
关键字引起的。删除它使错误消失。

@Transactional
从方法级移动到类级如何?
在类似的情况下也为我工作过,但我不能100%确定原因。

我在使用Hibernate和Spring Jpa数据存储库时也遇到过同样的问题。我忘了将
@Transactional
放在spring数据存储库方法上


在用
@Transactional

注释后,它对我有效。在我的情况下,我导入了错误的
@Transactional

正确的答案是:

import org.springframework.transaction.annotation.Transactional;
而不是

import javax.transaction.Transactional;

在我的项目中将Spring 4与Hibernate 5集成并遇到此问题后,我发现通过将会话的获取方式从
sessionFactory.openSession()
更改为
sessionFactory.getCurrentSession()
,可以防止出现错误。 解决此错误的正确方法可能是继续为绑定事务使用同一个会话。opensession将始终创建一个新会话,它与前一个会话不同,后者持有已配置的事务。使用getCurrentSession并添加附加属性
org.springframework.orm.hibernate5.SpringSessionContext
可以很好地用于我。

我也犯了同样的错误

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

更新:


我建议使用
org.springframework.transaction.annotation.Transactional中Spring的
@Transactional
注释

我遇到了相同的异常“TransactionRequiredException执行更新/删除查询”,但对我来说,原因是我在springapplicationContext.xml文件中创建了另一个bean,名为“transactionManager”引用“org.springframework.jms.connection.jmstransactionmanagerr”但是有另一个bean同名“transactionManager”引用“org.springframework.orm.jpa.JpaTransactionManager”。因此jmsbean超过了jpabean


重命名Jms的bean名称后,问题得到解决。

我在Java SE中尝试在非JTA(即资源本地)实体管理器中运行批量更新查询时收到此异常。
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:)
我只是忘了把我的JPQL代码包装进去

em.getTransaction().begin();


只需在方法级别或类级别添加@Transactional。当您更新或删除记录时,您必须维护事务的持久性状态,并且
@Transactional
管理此状态


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

我在类级别添加
@Transactional注释和导入org.springframework.transaction.annotation.Transactional时遇到了相同的错误

然后我意识到,因为我使用的是hibernate查询,所以我导入了
javax.persistence.query
,而不是
import org.hibernate.query.query
em.getTransaction().commit();
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.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;
    }
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class SearchRepo {
---
}
@EventListener(ContextRefreshedEvent.class)
@Transactional
public void methodName() {...}