public IvcValidationResponseDto findByInvitedCode(String inviteCode) {
IvcValidationResponseDto ivcValidationResponseDto = jpaQueryFactory.select(
new QIvcValidationResponseDto(
qInvited.seq,
qInvited.createdDate,
qInvited.modifiedDate,
qInvited.paymentStatus,
qMember.nickname
)
)
.from(qInvited)
.innerJoin(qInvited.member, qMember)
.fetchJoin()
.where(
qInvited.invitedCode.eq(inviteCode)
)
.fetchOne();
return ivcValidationResponseDto;
}
위 코드를 보면 @QueryProjection 을 이용하여 만든 qclass DTO 를 조회하는중이다.
엔티티를 조회하는게 아니고 dto 를 조회하는데 fetch join 을 쓰는것이 문제였던것이다.
fetch join 을 사용하는 이유는 엔티티 상태에서 엔티티 그래프를 참조하기 위해서 사용하는 것이라고한다.
따라서 엔티티가 아닌 DTO 상태로 조회하는 것은 불가능하다고한다.
그렇다면 해결법은 무엇이냐?
순수 join 을 사용하면 깔끔하게 동작한다.
참조 링크
public IvcValidationResponseDto findByInvitedCode(String inviteCode) {
IvcValidationResponseDto ivcValidationResponseDto = jpaQueryFactory.select(
new QIvcValidationResponseDto(
qInvited.seq,
qInvited.createdDate,
qInvited.modifiedDate,
qInvited.paymentStatus,
qMember.nickname
)
)
.from(qInvited)
.innerJoin(qInvited.member, qMember)
.where(
qInvited.invitedCode.eq(inviteCode)
)
.fetchOne();
return ivcValidationResponseDto;
}
일반적인 join 은 가져오지 않은 필드에 대해선 영속성에 관여하지 않는다는것이다.
가져오지않은 필드를 쓰려면 추가적인 쿼리가 발생할것이며 n+1 문제로 성능저하로 이어질것이다.
실제 필요한 컬럼들만 조회해야 할때에는 일반적인 조인이 효과적일것이며,
연관관계가 걸려있는 Entity의 정보도 같이 사용해야할때에는 fetch join이 맞는판단 인거같다.