【问题标题】:TransactionRequiredException Executing an update/delete queryTransactionRequiredException 执行更新/删除查询
【发布时间】:2014-11-07 10:01:01
【问题描述】:

您好,我正在使用带有 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>

我在代码中应用了一些更改,但它们没有效果。 谁能帮我解决这个问题。 提前致谢。

【问题讨论】:

  • 尝试删除em.getTransaction().begin();em.getTransaction().commit();em.flush();em.clear();em.close();它应该由春天来管理您的交易
  • 感谢您的回复,我已经尝试过您的建议,但他们没有改变。
  • Hibernate JPA(Spring Data JPA) with mongo?我不认为它会工作 - Mongo 是 NoSQL 不符合 ACID 属性。 spring-data-mongodb 是你应该使用的东西。

标签: java spring hibernate mongodb jpa


【解决方案1】:

我遇到了同样的异常并通过保存实体循环,例如:

relationships.stream().parallel().forEach

修改为:

  relationships.forEach

现在它可以工作了。

【讨论】:

    【解决方案2】:

    听从Baeldung JPA Transaction Required Exception的建议

    基本上将您的提交代码包装在

    Transaction transaction = session.beginTransaction();
    ....update or save or delete here
    transaction.commit();
    

    【讨论】:

      【解决方案3】:

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

      在您的情况下,它可能是 "javax.transaction.Transactional"

      【讨论】:

      • 当我使用“org.springframework.transaction.annotation.Transactional”时它工作正常
      【解决方案4】:

      我遇到了同样的错误。

      我只是在方法上添加了javax.transaction.Transactional@Transactional注解。

      更新:

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

      【讨论】:

        【解决方案5】:

        在不同的情况下,我也遇到了同样的异常。 由于我一直在这里寻找答案,也许它会对某人有所帮助。

        我的情况是异常发生了,因为我从 SERVICE CONSTRUCTOR... 调用了(正确注释的)@Transactional 方法 由于我的想法只是让这个方法在开始时运行,我将其注释为如下,并停止以错误的方式调用。异常消失了,代码更好了:)

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

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

        【讨论】:

          【解决方案6】:

          如果前面的答案失败,请确保您使用 @Service 构造型作为您在存储库中调用更新方法的类。我最初使用 @Component 代替,但它不起作用,对 @Service 的简单更改使其起作用。

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

              【解决方案8】:

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

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

              我希望这个想法对某人有所帮助。

              【讨论】:

                【解决方案9】:

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

                在使用 @Transactional 注释后,它对我有用。

                【讨论】:

                • 这对我有帮助……我在 JPA 存储库方法中需要“@Transactional”和“@Modifying”。仅在我的服务方法(调用 JPA 存储库)上使用它似乎还不够。
                • 这对我有帮助。 JPA DAO 存储库方法也需要 @Transactional!逆天!你是救生员,Satya P!!
                • 同意,如果使用@Modifing 查询,这是必需的。
                【解决方案10】:

                使用@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;
                    }
                

                【讨论】:

                  【解决方案11】:

                  使用@Modifying 和@Transaction 修复了我

                  1. @Modifying @Query(value="DELETE FROM lock WHERE user_id = ?1" ,nativeQuery=true) void deleteByUserId(Long userId);

                  2. @服务 @事务

                  【讨论】:

                    【解决方案12】:

                    就我而言,我输入了错误的@Transactional

                    正确的是:

                    import org.springframework.transaction.annotation.Transactional;
                    

                    不是

                    import javax.transaction.Transactional;
                    

                    【讨论】:

                    • 我尝试了两者(一次一个),并且两者都适用。使用的 Spring 版本是 2.2.5.RELEASE。我把弹簧留在了代码中。
                    【解决方案13】:

                    运行代码时的错误消息:

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

                    【讨论】:

                      【解决方案14】:

                      遇到同样的问题,我只是忘了用@EnableTransactionManagement注解激活事务管理。

                      参考:

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

                      【讨论】:

                        【解决方案15】:

                        只需在方法级别或类级别添加 @Transactional。当您更新或删除记录时,您必须维护 Transaction 的持久状态,@Transactional 负责管理。

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

                        【讨论】:

                          【解决方案16】:

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

                          我正在从持久性 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(),并且我的本机查询更新有效。

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

                          【讨论】:

                          • 对于那些阅读本文的人,要调用 joinTransaction 你做 em.joinTransaction(); (其中 em 是您的 EntityManager 对象)(此外,上面答案中函数的拼写之一是错误的,这就是为什么如果您只是复制/粘贴,您会在 Eclipse 中得到红色波浪线。相反,您可以复制/在此处粘贴此评论中的代码。)
                          • 使用第三个解决方案我得到这个错误:org.springframework.dao.InvalidDataAccessApiUsageException: No local transaction to join;嵌套异常是 javax.persistence.TransactionRequiredException: No local transaction to join
                          • 我改用了工厂,在每一个方法中我都得到了 entityManager 并使用 transaction.begin 和 commit() EntityManager entityManager = entityManagerFactory.createEntityManager(); 手动处理事务;
                          • 当你玩原生查询时,这应该被接受为答案,你需要做entityManager.joinTransaction();
                          • 我真是瞎了眼!感谢您的建议...我只是忘记了@Transactional 注释
                          【解决方案17】:

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

                          em.getTransaction().begin();
                          

                          em.getTransaction().commit();
                          

                          【讨论】:

                            【解决方案18】:
                            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:)
                            

                            【讨论】:

                            • 这是一个糟糕的答案,您应该为此使用准备好的声明。此代码容易受到注入攻击。
                            【解决方案19】:

                            我遇到了同样的异常“TransactionRequiredException Executing an update/delete query”,但对我来说,原因是我在 spring applicationContext.xml 中创建了另一个 bean名称为“transactionManager”的文件指的是“org.springframework.jms.connection.JmsTransactionManager”,但是还有另一个同名的bean“transactionManager”指的是“org.springframework.orm.jpa.JpaTransactionManager”。所以 JPA bean 被 JMS bean 覆盖。

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

                            【讨论】:

                              【解决方案20】:

                              在我的项目中集成 Spring 4 和 Hibernate 5 并遇到这个问题后,我发现我可以通过将获取会话的方式从 sessionFactory.openSession() 更改为 sessionFactory.getCurrentSession() 来防止出现错误。 解决此错误的正确方法可能是继续为绑定事务使用相同的会话。opensession 将始终创建一个新会话,该会话不喜欢前一个持有事务配置的会话。使用 getCurrentSession 并添加附加属性 &lt;property name="current_session_context_class"&gt;org.springframework.orm.hibernate5.SpringSessionContext&lt;/property&gt; 工作正常我。

                              【讨论】:

                                【解决方案21】:

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

                                【讨论】:

                                • 编辑没有添加或改进解决方案,因此没有必要。感谢您(您认为)改进的语法。我会更喜欢一种更有成效的方法。
                                • 要注意的另一件事是,包级别的可见性不适用于标记为 @Transactional 的方法。它必须是公开的。根据这篇文章:baeldung.com/transaction-configuration-with-jpa-and-spring,“使用代理的另一个注意事项是,只有公共方法才应该使用 Transactional 进行注释 - 任何其他可见性的方法将简单地忽略注释,因为它们没有被代理。”
                                【解决方案22】:

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

                                【讨论】:

                                • 这行得通。导入import org.springframework.transaction.annotation.Transactional; 并将@Transactional 添加到类级别。
                                • 我也不知道为什么,我尝试将 '@Transactional' 添加到所有不同的方法中,但没有成功,但是一旦将其移至类级别,奇迹就发生了......跨度>
                                • 您是否将它们添加到私有方法中?如果是这样,@Transactional 对它们没有影响。在这种情况下,添加类可能会有所帮助。
                                【解决方案23】:

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

                                【讨论】:

                                • 嗨@sanket 感谢您的回复我已经尝试过你的建议我得到了同样的错误。
                                • 我已经编辑了我的解决方案。往上看。问题似乎与您的配置文件有关。
                                • 它在没有 jpa 适配器的情况下通过添加 @Transactional(readOnly = false,isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) 工作,但它不会进入数据库。集合未在数据库中创建
                                • 我在我的解决方案中错过了 bean "entityManagerFactory。我已经编辑了我的解决方案
                                • 如果我使用 Jpa 供应商适配器,它会显示一些错误,所以请您指定我没有 jpa 供应商适配器。因为这里我用的是mongodb
                                猜你喜欢
                                • 2012-09-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2023-03-26
                                • 2013-04-18
                                • 1970-01-01
                                • 2014-09-23
                                • 2019-07-16
                                • 1970-01-01
                                相关资源
                                最近更新 更多