让我们假设我们有一个带有自定义方法的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作为返回类型!
是否有人知道另一种轻松允许的方式,当然除了显而易见的“在存储库和调用者之间为这些事情添加服务层”......
答案 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
另一种方法是,您可以实现自定义存储库实现,并在完成查询执行后返回更新后的实体。
答案 2 :(得分:0)
@Modifying(clearAutomatically=true)
它对我有用。