Spring Data Repository @Query - 更新并返回修改后的实体

时间:2018-04-06 10:24:06

标签: java spring spring-data

让我们假设我们有一个带有自定义方法的Spring Data存储库接口......

@Modifying
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
void markAsSoftDeleted(long id);

此方法只需设置实体的deletedAt字段即可。有没有办法允许此方法返回MyEntity的更新版本?

...显然

@Modifying
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
MyEntity markAsSoftDeleted(long id);

...不起作用,因为......

  

java.lang.IllegalArgumentException:修改查询只能使用void或int / Integer作为返回类型!

是否有人知道另一种轻松允许的方式,当然除了显而易见的“在存储库和调用者之间为这些事情添加服务层”......

3 个答案:

答案 0 :(得分:2)

有两种方法可以做到:

JPA惯用方式是首先加载实体,然后使用Java代码对其进行更改。

在事务中执行此操作会将更改刷新到数据库。

如果您坚持要进行批量更新,则需要将实体标记为更新的一部分。可能带有时间戳,也许更新本身已经标记了它们。然后,使用在更新过程中使用标记集的select语句重新加载它们。

请注意,您必须确保实体在EntityManager中尚不存在,否则,您将保留旧状态。这是其他答案推荐的@Mdoifying(clearAutomatically=true)的目的。

答案 1 :(得分:1)

在@Modifying批注上设置 clearAutomatically 属性。这将清除EntityManager中所有未刷新的值。

@Modifying(clearAutomatically=true)
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
MyEntity markAsSoftDeleted(long id);

要在提交更新之前刷新更改,最新的spring-data-jpa在@ModifyingAttribute上有另一个属性。但我认为它仍然在2.1.M1发布。

@Modifying(clearAutomatically=true, flushAutomatically = true)

请检查相应的jira错误请求:https://jira.spring.io/browse/DATAJPA-806

另一种方法是,您可以实现自定义存储库实现,并在完成查询执行后返回更新后的实体。

参考:Spring data jpa custom repository implemenation

答案 2 :(得分:0)

@Modifying(clearAutomatically=true)

它对我有用。