Spring Boot/JPA
일반 join + Dto 바로 반환 (feat. N+1 문제)
최-코드
2024. 9. 1. 17:24
상황 : QueryDsl을 통해 fetch join을 한 이후 Dto로 바로 반환하려고 했는데 에러가 발생했다.
원인
- fetch join을 사용하면 엔티티 그래프 기능을 사용하게 된다.
- 엔티티 그래프는 엔티티들 끼리 서로 연관되어 있는 관계를 그래프로 표현한 것으로, jpa가 어떤 엔티티를 불러올 때 이 엔티티와 관계된 엔티티를 불러올 것인지에 대한 정보를 제공한다.
- 엔티티 그래프는 엔티티만을 반환하기 때문에 Dto로 반환할 수 없다.
해결책 : 일반 join만을 사용하면 Dto로 반환할 수 있다. 이 때 JPQL 쿼리 자체가 필요한 데이터를 명시적으로 선택하여 가져오기 때문에, 연관된 엔티티를 추가적으로 조회하는 Lazy Loading이 동작하지 않는다. 따라서 N+1 문제가 발생하지 않는다.
@Override
public List<CommentResponseDto> findAllByPostId(Long postId) {
QCommentEntity parent = new QCommentEntity("parent");
return jpaQueryFactory
.select(new QCommentResponseDto(
commentEntity.id,
commentEntity.content,
commentEntity.reportCount,
parent.id,
user.nickname
))
.from(commentEntity)
.join(commentEntity.user, user)//.fetchJoin()하면 오류 발생
.leftJoin(commentEntity.parent, parent)//.fetchJoin()하면 오류 발생
.orderBy(commentEntity.id.asc())
.fetch();
}