본문 바로가기
스프링/JPA

JPA 변경/삭제 @Modifying

by 공부 안하고 싶은 사람 2021. 6. 4.
반응형

SpringDataJpa에서 deleteByXXX 등의 메소드 사용시

  • 삭제 대상들을 전부 조회하는 쿼리가 1번 발생한다.
  • 삭제 대상들은 1건씩 삭제 된다.
  • cascade = CascadeType.DELETE으로 하위 엔티티와 관계가 맺어진 경우 하위 엔티티들도 1건씩 삭제가 진행된다.

-> 해결 : 직접 범위 조건의 삭제 쿼리(JPQL)을 생성

@Transactional
@Modifying
@Query("delete from Customer c where c.id in :ids")
void deleteAllByIdInQuery(@Param("ids") List<Long> ids);
  1. 기본 함수인 deleteInBatch(Iterable entities) 이용 : 좋은 방법이지만 삭제하고자 하는 Entity들을 메모리상에 가져와서 호출해야 하는 단점
  2. @Modifying 이용 : 자유롭게 조건을 설정하여 단 한 번의 쿼리로 Bulk Delete
    • 벌크 연산은 1차 캐시를 포함한 영속성 컨텍스트를 무시하고 바로 Query를 실행하기 때문에 영속성 컨텍스트는 데이터 변경을 알 수가 없습니다.
      -> clearAutomatically를 true로 변경해준다면, 벌크 연산 직 후 자동으로 영속성 컨텍스트를 clear 해줍니다.
    • 그래서 조회를 실행하면 1차캐시에 해당 엔티티가 존재하지 않기 때문에 DB 조회 쿼리를 실행하게 됩니다.
    • Hibernate의 FlushModeType의 Default 값은 AUTO입니다.
    • 그래서 @Modifying(flushAutomatically = false)여도 해당 쿼리 메서드 실행 전 flush가 실행됩니다.
      -> FlushModeType의 값을 COMMIT으로 변경
      flushAutomatically의 Default 값인 false를 그대로 사용하게 되면, 쿼리 메서드 실행 시 flush가 실행이 되지 않습니다. 즉, 필요한 경우에 flush를 강제 호출하거나, @Modifying 같은 경우에는 flushAutomatically를 true로 변경해야 합니다.

 

https://ykh6242.tistory.com/105

 

728x90
반응형

'스프링 > JPA' 카테고리의 다른 글

Envers / spring-data-envers  (0) 2021.08.03
JPA 최적화, Hint  (0) 2021.06.04
FK가 PK가 아닌 다른 컬럼과 연관관계가 있을 때  (0) 2021.05.31
복합키  (0) 2021.05.26
전체 컬럼 매핑은 필수? DB default값  (0) 2021.05.26

댓글