【问题标题】:How to run custom update query on JpaRepository?(TransactionRequiredException)如何在 JpaRepository 上运行自定义更新查询?(TransactionRequiredException)
【发布时间】:2020-01-14 12:56:00
【问题描述】:

我正在尝试在 spring 中编写 2 个本机 SQL 查询,

我在服务类中使用 SQL 的查询注释是:

    @Transactional
    @Scheduled(cron = "0 0/1 * * * *")
    void testMethod() {

    String query = "UPDATE BUDGET_GROUP_SPEND_SUMMARY BSS, USER U, EMPLOYEE_MOVE_STAGE EMS, BUDGET B, SERVICE_GROUP SG " +
                "SET BSS.BULK_RECALC_LOCK = true " +
                "WHERE BSS.EMPLOYEE_ID = U.USER_ID " +
                "AND U.USER_ID = EMS.USER_ID " +
                "AND BSS.BUDGET_GROUP_ID = B.BUDGET_ID " +
                "AND B.BUDGET_SERVICE_GROUP_ID IS NOT NULL " +
                "AND EMS.MOVE_STAGE_ID IN (1,2) " +
                "AND U.USER_CUSTOMER_STATUS IN ('MOVE_COMPLETED', 'LOST', 'GET_FEEDBACK', 'CLOSED_NO_FEEDBACK', 'ON_ASSIGNMENT') " +
                "AND B.BUDGET_SERVICE_GROUP_ID = SG.SERVICE_GROUP_ID " +
                "AND SG.MOVE_STAGE_ID = 1";

        Query nq = entityManager.createNativeQuery(query);

        nq.executeUpdate();
    }

但是我收到了这个错误:

2019-09-12 18:28:00,012 ERROR [] o.s.s.s.TaskUtils$LoggingErrorHandler:95 - Unexpected error occurred in scheduled task.
javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

如果我使用entityManager.getTransaction().begin();entityManager.getTransaction().commit();

然后它的投掷:

2019-09-12 18:36:00,007 错误 [] os.s.s.TaskUtils$LoggingErrorHandler:95 - 发生意外错误 在计划任务中。 java.lang.IllegalStateException:不允许 在共享 EntityManager 上创建事务 - 使用 Spring 事务 或 EJB CMT 在 org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManager

为什么会出现这个错误?

或者有没有其他更好的方法来使用Jpa Repository 实现自定义更新查询?

【问题讨论】:

  • 你能分享persistence.xml吗?检查事务类型上的配置

标签: java sql hibernate jpa jpql


【解决方案1】:
  1. 我假设 Spring 不会创建事务代理,因为您的方法不是 public
  2. 如果您使用声明式 Spring 事务管理器,则应始终尝试避免手动事务管理
  3. 您的应用程序应该有一个处理数据库调用的单独层。在您的情况下,它是 JPA 存储库。因此最好在自定义 Jpa 存储库中实现查询,在此处注入其实例并调用适当的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 2012-09-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多