JPA JOIN FETCH 엔티티 중복

지찬우·2023년 3월 16일
0

Knowing

목록 보기
9/10
post-thumbnail

JOIN FETCH 사용 시 엔티티 중복 문제❗️

기존에는 도서 목록을 전송할 때는 도서의 id와 도서 이름, 저자만 전송을 했었지만 태그도 함께 전송해 달라는 요구사항이 추가되어 JOIN FETCH를 사용해 태그도 함께 조회하여 영속화하도록 JPQL을 수정했다. API 호출을 해봤는데 아래 보이는 것처럼 엔티티가 중복되어 전송되었다.


처음에는 DB에 쿼리가 잘못 날아가나 싶었다. 하지만 쿼리에는 이상이 없었다.


중복된 엔티티의 개수가 태그 개수와 맞아떨어졌다. 그래서 태그가 두 개인 도서도 테스트해 보았더니 역시 두 개가 중복되어 전송되었다.

DB에 쿼리를 직접 날려보면 당연하게 3개의 row가 조회된다. 나는 이때까지 hibernate가 DB에서 조회된 row를 엔티티로 영속화할 때 당연히 중복을 처리해 줄 것이라고 생각했었다.


해결💡

최근에 구매한 김영한 님의 ‘자바 ORM 표준 JPA 프로그래밍’ 책을 열어 열심히 찾아보았다. 패치 조인 부분 내용을 쭉 살펴보다가 ‘패치 조인과 DISTINCT’라는 소제목이 눈에 들어왔다. DISTINCT는 데이터베이스를 공부할 때 분명 배웠었지만 그동안 사용한 적이 없어 잊고 있었다. 이는 중복되는 row를 제거해 주는 SQL의 명령어이다.

하지만 JPQL의 DISTINCT는 추가적인 기능이 있다.

SQL의 DISTINCT는 중복된 결과를 제거하는 명령어다. JPQL의 DISTINCT 명령어는 SQL에 DISTINCT를 추가하는 것은 물론이고 애플리케이션에서 한 번 더 중복을 제거한다.
*’
자바 ORM 표준 JPA 프로그래밍’*

SQL에 DISTINCT 명령어를 추가해 봤지만 마찬가지로 3개의 row가 조회되었다. 당연하다. book_tag_idtag_id, tag_name 등의 속성들의 값이 다르기 때문에 중복된 row라고 할 수 없다.


JPQL은 SQL에 DISTINCT 명령어를 추가할 뿐 아니라 애플리케이션에서 중복을 한 번 더 처리하기 때문에 중복되는 엔티티를 모두 제거해 준다. 이렇게 잘 해결할 수 있었다!


profile
좋은 개발자가 되자.

0개의 댓글