JPA에서 변경에 사용하는 변경감지 기능은 한건한건씩 진행한다.
만약 전 직원의 연봉을 10% 인상해야한다면? 모든 직원을 하나하나 조회하여 Dirty Checking으로 변경하는 것은 매우 비효율적이다.
이런 경우에는 DB에 update쿼리를 날려 한번에 모두 변경하고 commit을 하는 것이 더 효율적일 것이다.이를 JPA에서 벌크성 수정 쿼리라고 한다.
먼저 JPA를 사용하여 벌크성 수정 쿼리를 작성해보자.
파라미터로 넘어온 나이보다 나이가 많은 모든 사람의 나이를 한살 증가시켜주는 update쿼리를 작성하였다.
이를 스프링 데이터 JPA로 작성해보자.
@Query 애노테이션을 사용하여 JPQL을 작성하고 @Param으로 파라미터를 바인딩해준다.
@Modifiying은 JPA에서의 excuteUpdate를 호출해준다. 만약 update를 한다면 @Modifying 애노테이션을 꼭 붙혀주자.
만약 @Modifying 애노테이션을 붙혀주지 않으면 org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations 에러가 발생한다.
주의해야할 점!!!!!
벌크성 쿼리는 영속성 컨텍스트를 무시하고 바로 DB에 쿼리를 날리는 것이기 때문에 영속성 컨텍스트에는 과거의 값이 남아있다. 위와 같은 코드를 예시로 들면, DB에는 41살로 update가 되었지만 영속성 컨텍스트에는 member5의 나이는 40살이다. 따라서 만약 위와 같은 상태에서 회원을 조회한다면 기대했던 값과 달라서 문제가 발생한다.(40살로 나옴)
@Modifying(clearAutomatically = true) (이 옵션의 기본값은 false ) : 벌크성 쿼리를 실행하고 나서 영속성 컨텍스트 초기화시켜주는 옵션이다. 만약 다시 조회해야 하면 꼭 영속성 컨텍스트를 초기화 하자.
영속성 컨텍스트를 초기화!!
이와 같이 EntityManger로 초기화 시켜주어도 무방하다.
'Spring > Spring Data JPA' 카테고리의 다른 글
JPA Hint, Lock (0) | 2021.06.14 |
---|---|
@EntityGraph (0) | 2021.06.14 |
페이징과 정렬 (0) | 2021.06.13 |
쿼리 메서드 기능 (0) | 2021.06.11 |
Spring Data JPA 공통 인터페이스 (0) | 2021.06.10 |