Spring Data Repository @Query - Update and return modified entity

落爺英雄遲暮 提交于 2020-06-21 04:05:11

问题


let's assume we have a Spring Data repository interface with a custom method...

@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. Is there any way to allow this method to return an updated version of the 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!

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"...


回答1:


Set clearAutomatically attribute on @Modifying annotation.That will clear all the non-flushed values from 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. But I think its still in 2.1.M1 release.

@Modifying(clearAutomatically=true, flushAutomatically = true)

Please check corresponding jira bug request: 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




回答2:


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.

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.

Note that you have to ensure that the entities don't exist yet in your EntityManager, otherwise you will keep the old state there. This is the purpose of @Mdoifying(clearAutomatically=true) recommended by other answers.




回答3:


@Modifying(clearAutomatically=true)

Its works for me.



来源:https://stackoverflow.com/questions/49690671/spring-data-repository-query-update-and-return-modified-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!