java - Spring JPA更新并返回更新后的数据

标签 java spring spring-boot jpa spring-data-jpa

如何构建一个 JPA 方法,在使用 JPA 查询更新时可以返回更新后的数据? 我已经创建了类似的东西。

@Transactional
@Modifying
@Query("UPDATE User u SET u.isActive = true"
      + " WHERE u.isActive = false AND u.reactivateTime <= currentTime"
      + " AND u.reactivateTime IS NOT null")
int reactivateUser(@Param("currentTime") ZonedDateTime currentTime);

但是,我想要的是它返回用户列表。如果我直接改成这样

@Transactional
@Modifying
@Query("UPDATE User u SET u.isActive = true"
      + " WHERE u.isActive = false AND u.reactivateTime <= currentTime"
      + " AND u.reactivateTime IS NOT null")
List<User> reactivateUser(@Param("currentTime") ZonedDateTime currentTime);

就会出现这样的错误。

IllegalStateException: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations

最佳答案

正如您所发现的,仅更改方法的返回类型不会导致自动生成的 JPA 方法返回不同的类型。

问题是您正在执行批量更新操作。这将在执行时转换为等效的 SQL“update...where”语句,并且 JDBC 将返回的唯一数据是更新的行数。 (顺便说一句,在这种情况下,您应该返回一个 long,而不是 int)。

所以,你必须设计一些其他方法来做到这一点。 临时,我可以想到两种方法:

  1. 如果您可以非常确定您将始终更新相对较少的行数(例如,最多几百行),那么您可以创建一个方法来选择您想要的实体实例更新,例如

    @Query("SELECT u from User" + " WHERE u.isActive = false AND u.reactivateTime <= currentTime" + " AND u.reactivateTime IS NOT null")
    List<User> getUsersToReactivate(@Param("currentTime") ZonedDateTime currentTime);
    

然后,在 JPA Repository 接口(interface)的具体实现中,

  • 调用该方法来检索实体。
  • 通过java代码更新实体
  • 保存实体

例如(我刚刚输入了这个,没有尝试 - 语法错误是你的责任):

@Transactional
@Modifying
List<User> reactivateUsers(ZonedDateTime currentTime) {
   List<User> users = getUsersToReactivate(currentTime);
   users.forEach(user -> {
       user.setActive(true);
       save(user);
   ); 
   return users; 
}
  • 这可能更具侵入性,但您可以向 User 类添加一个名为“lastUpdated”的 Date 属性,获取当前日期,将 isActive 标志更新为 true,将“lastUpdated”属性更新为当前日期,然后选择LastUpdate 属性是当前日期的实体。
  • 关于java - Spring JPA更新并返回更新后的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61472442/

    相关文章:

    java - 具有重复属性的 Spring Boot 多个数据源

    java - JsonObject getAsString 抛出异常

    spring - thymeleaf :each two iterate two listings

    java - 单选按钮标签更改

    spring - JsonParser 已弃用

    spring - Apache Tomcat 设置 java.lang.NoClassDefFoundError : org/springframework/asm/ClassVisitor

    Java 反射泛型 - 通过在编译时传递参数进行转换?

    java - IBM Filenet p8 中的自定义订阅错误

    java - Java 中的过滤(未打印)日志记录和性能

    java - @DateTimeFormat 无法识别