반응형
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);
- 기본 함수인 deleteInBatch(Iterable entities) 이용 : 좋은 방법이지만 삭제하고자 하는 Entity들을 메모리상에 가져와서 호출해야 하는 단점
- @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로 변경해야 합니다.
- 벌크 연산은 1차 캐시를 포함한 영속성 컨텍스트를 무시하고 바로 Query를 실행하기 때문에 영속성 컨텍스트는 데이터 변경을 알 수가 없습니다.
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 |
댓글