问题
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