Why should we use @Modifying annotation for queries in Data Jpa

for example, I have a method in my CRUD interface that removes a user from the database:

public interface CrudUserRepository extends JpaRepository<User, Integer> {

    @Transactional
    @Modifying
    @Query("DELETE FROM User u WHERE u.id=:id")
    int delete(@Param("id") int id, @Param("userId") int userId);
}

This method will only work with @Modification annotation. But what does the annotation need here? Why can not spring analyze the request and understand that it is a modifying request?

+37
source share
3 answers

, , , . EntityManager , ( . JavaDoc of EntityManager.clear()). , EntityManager. , EntityManager , @Modifying clearAutomatically false,

: -

http://docs.spring.io/spring-data/jpa/docs/1.3.4.RELEASE/reference/html/jpa.repositories.html

+35

CAUTION!

@Modifying(clearAutomatically=true) . :

, . EntityManager , (. JavaDoc EntityManager.clear() ), EntityManager. , EntityManager , @Modifying clearAutomatics true.

, Spring Boot 2.0.4.RELEASE Spring Data flushAutomatically (https://jira.spring.io/browse/DATAJPA-806) https://docs.spring.io/spring-data/jpa/docs/2.0.4.RELEASE/api/org/springframework/data/jpa/repository/Modifying.html#flushAutomatically

@Modifying:

@Modifying(clearAutomatically=true, flushAutomatically=true)

, ?

:

repo {
   @Modifying
   @Query("delete User u where u.active=0")
   public void deleteInActiveUsers();

}

1, flushAutomatically

 service {
        User johnUser = userRepo.findById(1); // store in first level cache
        johnUser.setActive(false);
        repo.deleteInActiveUsers();// BAM it won't delete JOHN

        // JOHN still exist since john with active being false was not 
        // flushed into the database when @Modifying kicks in
    }

2, clearAutomatically , johnUser.active

service {
       User johnUser = userRepo.findById(1); // store in first level cache
       repo.deleteInActiveUsers(); // john is deleted now 
       System.out.println(userRepo.findById(1).isPresent()) // TRUE!!!
       System.out.println(userRepo.count()) // 1 !!!
       // JOHN still exist since in this transaction persistence context
       // was not cleared upon @Modifying query execution, John will still 
       // be fetched from 1st level cache 
       // 'clearAutomatically' takes care of doing the 
       // clear part on the object being modified
}

- - , @Modifying clearAutomatically & flushAutomatically , ,

+3

, @Modifying @Modifying INSERT, UPDATE, DELETE DDL.

@Modifying , SELECT.

+2

Source: https://habr.com/ru/post/1016835/


All Articles