[Spring] OrphanRemoval의 불편한 성능

HwangDo·2023년 12월 28일
0

JPA

목록 보기
6/7
post-thumbnail
post-custom-banner

JPA 쓸 때 편한 기능이 있다.
바로 orphanRemoval이다.

@OneToMany(mappedBy = "folder", orphanRemoval = true)
	List<Link> links = new ArrayList<>();

One측에서 orphanRemoval을 걸어두면, one측 엔티티를 지울 때 매핑된 Many들을 모두 같이 지워버릴 수 있다.
마치 게시글과 댓글의 관계를 생각해보면 편하다.
그렇다면, 쿼리는.. 어떻게 나갈까?
먼저, 이해를 돕기 위해 나는
FOLDER - LINK가 1:N으로 매핑되어 있다.

FOLDER를 삭제 할 경우 제일 먼저, FOLDER와 매핑된 LINK를 모두 조회한다.


그리고 매핑 된 링크가 N개라면, N개를 ID를 기반으로 하나하나 지운다.

마지막에 폴더를 지워준다.

아무리봐도 성능상 그냥 큰 손해같았다. 뭔가 머리속에 N+1 문제가 떠오르면서, 그거보다 손해같았다..
내가 코드 몇 줄 덜 짜겠다고 쿼리 한두번이 아닌, N번이 더나가는 문제는 수정해야 했다.


벌크 연산을 사용해보자.

    @Query("delete from Link l where l.folder = :folder")
    @Modifying(clearAutomatically = true, flushAutomatically = true)
    void deleteAllByFolder(@Param("folder") Folder folder);

LinkRepository에 직접 벌크 삭제 쿼리를 작성하자. @Modyfying 애노테이션을 붙여야, 더티체킹 패스하고 바로 우리가 원하는 쿼리가 날아간다.
그렇게 된다면, 영속성 Context는 이 사실을 알지 못한다. 따라서 clear && flush를 해줘 캐시를 초기화해주자.


변경 후엔 잘 작동 할까?

Repository에 쿼리 하나, Service에서 호출 하나 추가해서 아주 단순하게 고쳐졌다.

profile
제가 배워가는 내용과, 실수한 부분을 정리합니다
post-custom-banner

0개의 댓글