매핑 관계 중 삭제 쿼리

대영·2024년 7월 29일
2

트러블 슈팅

목록 보기
4/5

🙏내용에 대한 피드백은 언제나 환영입니다!!🙏

간단히 User <-> Restaurant이라고 가정

🚨 트러블 내용

양방향 매핑 관계에서 주인이 아닌 곳 (User Entity)를 삭제시키면 외래 키를 가지고 있는 주인 (Restaurant Entity에서의 user)에 대한 삭제 쿼리문을 보고자 한다.

@OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)

위 코드와 같이 cascade = CascadeType.REMOVE 속성을 사용하게 된다면 아래와 같이 매핑되어 있는 개수만큼 쿼리문을 날린다.

예시에는, User는 5개의 Restaurant과 연결되어 있고, FK값을 삭제시키려면, FK를 가리키고 있는 값들을 다 삭제해야 하기에 연관된 Restaurant의 데이터를 모두 삭제시킨 후 User를 삭제시킨다.

그 과정에서, 쿼리문에 많이 발생하게 되는 것이다.

❓ 왜 그런 것일까?

개별 삭제 쿼리문이 발생하는 이유는, Hibernate가 기본적으로 엔터티마다 독립적으로 삭제 작업을 수행하기 때문이다.

JPA는 엔터티를 일괄 처리하는 것이 아니라 하나씩 처리하는 것을 기본 동작으로 한다.

👉 해결방법

  1. 한번에 삭제하기 위하여 JPQL을 아래와 같이 삭제 쿼리문을 작성한다.
	@Modifying
    @Query("DELETE FROM Restaurant r WHERE r.user.id = :userId")
    void deleteByUserId(@Param("userId") Long userId);
  1. User 삭제 시, 위 로직을 호출한다.
	@Transactional
    public void deleteUser(Long userId) {
        restaurantRepository.ddeleteByUserId(userId);
        userRepository.deleteById(userId);
    }
  1. 결과

위와 같이 작성하면 위와 같이 하나의 쿼리문으로 삭제할 수 있다.

💡 느낀점

JPA의 간편함에만 의존하면 서버의 성능에 문제가 생길 수 있다는 것을 알 수 있게 되었다. 의심하고 또 의심하며 성능의 향상을 위해 공부를 해야겠다.

profile
Better than yesterday.

0개의 댓글