Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Repository @Query - Update and return modified entity

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

like image 787
Florian Schaetz Avatar asked Apr 06 '18 10:04

Florian Schaetz


People also ask

Which is better CrudRepository or JpaRepository?

Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.

How do you update data on a CrudRepository?

CrudRepository save() to Add a New Instance Notice that we never specified an id. The instance is initially created with a null value for its id, and when we call the save() method, an id is automatically generated. The save() method returns the saved entity, including the updated id field.

How do I update a JPA spring record?

ALTER TABLE customer ADD UNIQUE (email); Refactor save() method logic so that it checks if an entry exists in the database. If it does, update the existing entry. Otherwise, create a new one and insert it into the database.

How does @query work in spring boot?

The @Query annotation declares finder queries directly on repository methods. While similar @NamedQuery is used on domain classes, Spring Data JPA @Query annotation is used on Repository interface. This frees the domain classes from persistence specific information, which is a good thing.


2 Answers

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 @Modifying(clearAutomatically=true) recommended by other answers.

like image 173
Jens Schauder Avatar answered Oct 19 '22 00:10

Jens Schauder


@Modifying(clearAutomatically=true)

Its works for me.

like image 45
Felipe Guedes Avatar answered Oct 19 '22 00:10

Felipe Guedes