[JPA] fetch join

김형진·2023년 4월 28일
0

JPA에서 관리하는 Entity 객체 내의 참조 객체 필드는 기본적으로 Lazy 로딩으로 관리된다.
언제 어디서 객체 필드 참조가 필요할지 불분명하기 때문이다.

그렇다면 참조하는 객체가 필요할 때에는 그냥 접근하면 될까?
객체에 접근했을 때 참조 객체가 실제 객체가 아닌 Hibernate의 프록시 객체인 경우 알아서 DB에 한 번 더 쿼리를 날려 진짜 객체를 알아서 가져와준다.
편하긴 하겠지만, 참조 객체에 접근할 때마다 DB에 query가 한 번씩 더 나가기 때문에 성능이 저하된다는 문제점을 안고 있다.

이를 N+1문제라 하는데, 예를 들어 User객체를 먼저 조회해온 뒤, User가 참조하는 Team의 정보에 접근할 때 최대 유저의 수만큼 다시 Team을 조회하는 쿼리를 날려야 한다는 것이다. (물론 Team이 겹치는 User가 있는 경우 유저 수보다는 적은 쿼리를 날리게 될 것 이다.)
User가 Team뿐 아니라 다른 여러 객체를 참조하게 되면 최대 (유저 수 * 참조 객체) 만큼의 쿼리가 발생하게 된다.

그렇다면 이러한 경우 애초에 User가 참조하는 객체를 User조회 시 같이 가져오는 것이 성능에 더 나을 것이다.
그렇다고 함부로 LAZY로딩 설정을 풀 수는 없다.

이러한 경우 fetch join하는 쿼리를 보내는 로직을 하나 만들면 된다.
fetch join은 DB의 join과 같으며 jpa에서 사용하는 문법이다.
fetch join으로 원하는 테이블에 미리 join하여 원하는 객체의 정보를 User와 함께 담아오면 끝

그냥 join을 사용하면 안되는 이유는, 그냥 join을 사용해도 실제로 영속화되는건 주체가 되는 Entity, 즉 이 경우에는 User만 영속화되므로 Team의 데이터를 쓸 수 없다.
따라서 그냥 Join은 참조 객체를 검색조건으로 사용할 때만 거의 사용되며 실제로 참조객체의 데이터를 사용하기 위해서는 대상 객체를 영속화시켜주는 fetch join을 사용해야 한다.

profile
히히

0개의 댓글