programing

Data Jpa의 쿼리에 @Modifying 주석을 사용해야 하는 이유

magicmemo 2023. 9. 8. 21:22
반응형

Data Jpa의 쿼리에 @Modifying 주석을 사용해야 하는 이유

예를 들어 CRUD 인터페이스에 데이터베이스에서 사용자를 삭제하는 메서드가 있습니다.

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);
}

이 메서드는 주석 @Modifying에서만 작동합니다.하지만 여기에 주석이 필요한 것은 무엇입니까?스프링이 쿼리를 분석하고 수정 쿼리라는 것을 이해할 수 없는 이유는 무엇입니까?

주의!

을 해서.@Modifying(clearAutomatically=true) 중인 합니다. 다음입니다.

이렇게 하면 메서드에 주석이 달린 쿼리가 하나를 선택하는 대신 업데이트 쿼리로 트리거됩니다.수정 쿼리를 실행한 후 EntityManager에 오래된 엔티티가 포함되어 있을 수 있으므로 자동으로 삭제하지 않습니다(자세한 내용은 EntityManager.clear()의 JavaDoc 참조). 이렇게 하면 EntityManager에 여전히 보류 중인 모든 비 플러시 변경 사항이 효과적으로 삭제됩니다.EntityManager를 자동으로 지우려면 @Modifying 주석 지우기를 설정할 수 있습니다.true에 자동으로 연결합니다.

도, 부터부터 합니다.Spring Boot 2.0.4.RELEASE스프링 데이터 추가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 를 실행하기 전에 지속성 컨텍스트에서 관리 엔티티를 자동 플러시합니다.

그래서 가장 안전한 방법은@Modifyingsilitude:

@Modifying(clearAutomatically=true, flushAutomatically=true)

그 두 개의 깃발을 사용하지 않으면 어떻게 됩니까?

다음 코드를 고려합니다.

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

}

1 왜 1 flushAutomatically

 service {
        User johnUser = userRepo.findById(1); // store in first level cache
        johnUser.setActive(false);
        repo.save(johnUser);

        repo.deleteInActiveUsers();// BAM it won't delete JOHN right away
        
        // JOHN still exist since john with active being false was not 
        // flushed into the database when @Modifying kicks in
        // so imagine if after `deleteInActiveUsers` line you called a native 
        // query or started a new transaction, both cases john 
        // was not deleted so it can lead to faulty business logic 
    }

2 왜 2 clearAutomatically 다음에서는 johnUser.active가 이미 false임을 고려합니다.

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

- 에서 - 이 에서 에 하는 를 된 한 하는 한 를 @Modifying, 그럼 쓰시오clearAutomatically&flushAutomatically 않다면 수 .지이그을뛸다수면다수f뛸epg을지면n .

그건 그렇고 이것이 당신이 항상 그것을 넣어야 하는 또 다른 이유입니다.@Transactional서비스 계층에 주석을 추가하면 동일한 트랜잭션에서 관리되는 모든 엔티티에 대해 하나의 지속성 컨텍스트만 가질 수 있습니다.지속성 컨텍스트가 최대 절전 모드 세션으로 제한되므로 세션에 몇 개의 트랜잭션이 포함될 수 있음을 알아야 합니다. 자세한 내용은 이 답변을 참조하십시오. https://stackoverflow.com/a/5409180/1460591 스프링 데이터의 작동 방식은 트랜잭션을 함께 결합하는 것입니다.Transaction Propagation) 하나의 트랜잭션으로(기본 전파(필수)) 자세한 내용은 이 답변을 참조하십시오. https://stackoverflow.com/a/25710391/1460591

여러 개의 고립된 트랜잭션이 있는 경우 서로 연결합니다(e).g 서비스에 트랜잭션 주석이 없음) 따라서 스프링 데이터가 작동하는 방식을 따라 여러 세션이 발생하게 되므로 여러 개의 지속성 컨텍스트(일명 1차 레벨 캐시)를 사용할 경우에도 지속성 컨텍스트에서 엔티티를 삭제/삭제할 수 있음을 의미합니다.flushAutomatically삭제되거나 수정된 동일한 엔티티가 이미 다른 트랜잭션의 지속성 컨텍스트에서 가져오기 및 캐시될 수 있습니다. 이는 잘못된 데이터 또는 동기화되지 않은 데이터로 인해 잘못된 비즈니스 결정을 초래합니다.

그러면 메서드에 주석이 달린 쿼리가 선택 쿼리 대신 업데이트 쿼리로 트리거됩니다.수정 쿼리 실행 후 EntityManager에 오래된 엔티티가 포함되어 있을 수 있으므로 자동으로 삭제합니다(자세한 내용은 EntityManager.clear()의 JavaDoc 참조).이렇게 하면 Entity Manager에서 여전히 보류 중인 모든 비 플러시 변경 사항이 효과적으로 삭제됩니다.EntityManager가 자동으로 지워지지 않도록 하려면 @Modifying annotation's clear를 설정할 수 있습니다.false에 자동으로 속성 지정;

자세한 내용은 다음 링크를 참조할 수 있습니다.

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

다음이 필요한 쿼리@Modifying주석에는 INSERT, UPDATE, DELETE 및 DDL 문이 포함됩니다.

추가하기@Modifying주석은 쿼리가 SELECT 쿼리에 해당하지 않음을 나타냅니다.

사용할 때만@Query. 당신은석,은 select query를 사용합니다. 그러나 당신은@Modifying메소드 위에 있는 쿼리 삽입, 삭제, 업데이트를 사용할 수 있는 주석.

언급URL : https://stackoverflow.com/questions/43665090/why-do-we-have-to-use-modifying-annotation-for-queries-in-data-jpa

반응형