gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 08:39:24 26 4
gpt4 key购买 nike

如何构建一个 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/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com