[英]Spring Data Repository @Query - Update and return modified entity
let's assume we have a Spring Data repository interface with a custom method...假设我们有一个带有自定义方法的 Spring Data 存储库接口......
@Modifying
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
void markAsSoftDeleted(long id);
This method simply sets the deletedAt field of the entity, ok.这个方法简单的设置了实体的deletedAt字段,ok。 Is there any way to allow this method to return an updated version of the
MyEntity
?有什么方法可以让这个方法返回
MyEntity
的更新版本吗?
Obviously...显然……
@Modifying
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
MyEntity markAsSoftDeleted(long id);
...does not work, since... ...不起作用,因为...
java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as return type!
java.lang.IllegalArgumentException: 修改查询只能使用 void 或 int/Integer 作为返回类型!
Does anyon know another way to easily allow that, except of course the obvious "add a service layer between repository and caller for such things"...有没有人知道另一种方法可以轻松实现这一点,当然除了明显的“在存储库和调用者之间为此类事情添加服务层”...
Set clearAutomatically attribute on @Modifying annotation.That will clear all the non-flushed values from EntityManager.在@Modifying 注释上设置clearAutomatically属性。这将从 EntityManager 中清除所有未刷新的值。
@Modifying(clearAutomatically=true)
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
MyEntity markAsSoftDeleted(long id);
To flush your changes before committing the update latest spring-data-jpa has another attribute on @ModifyingAttribute.要在提交更新之前刷新您的更改,最新的 spring-data-jpa 在 @ModifyingAttribute 上有另一个属性。 But I think its still in 2.1.M1 release.
但我认为它仍然在 2.1.M1 版本中。
@Modifying(clearAutomatically=true, flushAutomatically = true)
Please check corresponding jira bug request: https://jira.spring.io/browse/DATAJPA-806请查看对应的jira bug请求: https : //jira.spring.io/browse/DATAJPA-806
Another approach can be you can implement custom repostiory Implementation and return your updated entity after done with the query execution.另一种方法是您可以实现自定义存储库实现并在完成查询执行后返回更新的实体。
Reference : Spring data jpa custom repository implemenation参考: Spring data jpa自定义存储库实现
There are two ways to do that:有两种方法可以做到这一点:
The JPA idiomatic way to do this is to load the entities first, then changing them using Java code.执行此操作的 JPA 惯用方法是首先加载实体,然后使用 Java 代码更改它们。
Doing this in a transaction will flush the changes to the database.在事务中执行此操作会将更改刷新到数据库。
If you insist on doing a batch update you need to mark the entities as part of the update.如果您坚持进行批量更新,则需要将实体标记为更新的一部分。 Maybe with a timestamp, maybe the update itself already marks them.
也许带有时间戳,也许更新本身已经标记了它们。 And then you reload them using a select statement that uses the marker set during the update.
然后使用在更新期间使用标记集的 select 语句重新加载它们。
Note that you have to ensure that the entities don't exist yet in your EntityManager
, otherwise you will keep the old state there.请注意,您必须确保实体在您的
EntityManager
尚不存在,否则您将保留旧状态。 This is the purpose of @Modifying(clearAutomatically=true)
recommended by other answers.这是其他答案推荐的
@Modifying(clearAutomatically=true)
的目的。
@Modifying(clearAutomatically=true)
它对我有用。
It will never return void
or your class type, add return type int
or Integer
like below,它永远不会返回
void
或您的类类型,添加返回类型int
或Integer
如下所示,
@Modifying(clearAutomatically=true)
@Transactional
@Query("UPDATE MyEntity SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?1")
Integer markAsSoftDeleted(long id);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.