0
votes

AFAIK @Modifying is there to take care of persistence context cleanup in case of INSERT/UPDATE/DELETE queries specified in @Query annotation.
But what is pure @Modifying good for? According to this post, is seems you should always write @Modifying(clearAutomatically=true, flushAutomatically=true).

The documentation says(link):

As the EntityManager might contain outdated entities after the execution of the modifying query, we do not automatically clear it ... since this effectively drops all non-flushed changes still pending in the EntityManager

So by default @Modifying do not clean (and do not flush). Then why should I add it to my @Query method?

3

3 Answers

1
votes

The @Modifying annotation is used to enhance the @Query annotation to execute not only SELECT queries but also INSERT, UPDATE, DELETE, and even DDL queries.

Let's play with this annotation a little and see what it's made of.

First, let's see an example of a @Modifying UPDATE query:

@Modifying
@Query("update User u set u.active = false where u.lastLoginDate < :date")
void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);

Let's try another one where we'll delete deactivated users:

@Modifying
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();

As we can see, this method returns an integer. It's a feature of Spring Data JPA @Modifying queries that provides us with the number of updated entities.

We should note that executing a delete query with @Query works differently from Spring Data JPA's deleteBy name-derived query methods. The latter first fetches the entities from the database and then deletes them one by one. Thus, this means that the lifecycle method @PreRemove will be called on those entities. However, with the former, a single query is executed against the database.

Finally, let's add a deleted column to our USERS table with a DDL query:

@Modifying
@Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();

Unfortunately, using modifying queries leaves the underlying persistence context outdated. However, it is possible to manage this situation.

0
votes

(clearAutomatically=true, flushAutomatically=true) they will be added to manage the state of the persistence context with the clearAutomatically and flushAutomatically properties. that will clear/flush the objects in the first level cache.

by using the @Modify the spring boot application gives a write permission to the DB to do these operations (UPDATE/INSERT/DELETE). @Query can be used alone to do GET and must use the @modify for other 3 modify operations to get the DB permission.

0
votes

It's mandatory for write operations on @Querys, that's why.

clearAutomatically and flushAutomatically allow you to decide whether to clear right after and flush right before respectively. If set to false (the default), then Spring Data will do it whenever it sees fit, trying to optimise access operations to the DB. It may not clear right after the operation, or flush right before, but it will still do it.