return jpaQueryFactory.select( reservation ) .from(reservation) .join(reservation.reservationMembers)
문제 탐색 및 배경 설명
1:N 관계의 테이블에서 QueryDsl을 이용해 부모, 자식 테이블을 함께 Join 하는 상황에서 예기치 못한 문제 발생
[org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.query.SemanticException: Could not interpret path expression 'reservationMember.memberType']
해당 문제에 관한 메타 코드는 링크 참고
where 절에 사용하는 reservationMember가 조인 시 별칭(Alias)로 선언되지 않아 QueuyDsl이 경로를 해석하지 못하는 상황
return jpaQueryFactory.select( reservation )
.from(reservation)
.join(reservation.reservationMembers)
.where(reservation.id.eq(reservationId).and(reservationMember.memberType.eq( ReservationMemberType.DRV_1ST))) .fetchOne();
문제 해결
위의 쿼리를 확인해보면 Join에서 reservation.reservationMembers에서 별도의 별칭을 정하지 않으면 where절 입장에서도 조건 시 reservationMember를 참조할 수가 없을 것이다 (어디로 참조해야하는지 모르기에)
그래서 별칭 지정을 통해 어떤 테이블을 참조할 것인 알려줘야하는데 이를 별칭을 통해 부여할 수 있음
return jpaQueryFactory
.select(reservation)
.from(reservation)
.join(reservation.reservationMembers, reservationMember) // 별칭 지정
.where(
reservation.id.eq(reservationId)
.and(reservationMember.memberType.eq(ReservationMemberType.DRV_1ST))
)
.fetchOne();
종합적으로 QueryDsl에서 조인된 엔티티를 where 절에서 사용하려면 그 엔티티를 참조할 경로를 명시해줘야함.
위의 코드에서 이러한 경로를 명시해주지 않았기에 SemanticException발생
별칭을 통해 select / where 등 해당 엔티티의 필드를 안전하게 참조 가능하다는 점
해당 문제를 해결하며 얻게된 추가 정보
1. 선언한 별칭을 일관되게 사용하라
별칭 선언 이후 별칭을 일관되게 사용하지 않으면 불필요한 조인 혹은 크로스 조인 발생 가능
2. 다중 조인시 주의할 것
jpaQueryFactory
.select(reservation)
.from(reservation)
.join(reservation.reservationMembers)
.join(reservation.reservationMembers.user)
샘플 코드에서 reservationMembers를 조인 후, 타겟 엔티티에 user를 한번 더 조인하게 되면 이미 조인된 reservationMembers를 사용하지 않고 새로운 reservationMembers를 조인해버림
결국 reservationMembers가 두 번 조인되고 테이블 혹은 데이터의 규모가 커질수록 성능 누수 발생
아래와 같이 수정할 것
jpaQueryFactory
.select(reservation)
.from(reservation)
.join(reservation.reservationMembers rm)
.join(rm.user, user)'오류발생과 해결' 카테고리의 다른 글
| JPQL의 DTO 중첩 구조의 데이터 바인딩 실패 여정으로부터 Hibernate에 닿기까지 (1) | 2026.02.12 |
|---|---|
| 왜 접속이 되지 않는걸까요.. 나의 작은 타임리프 (2) - 마무리(Sticky Session) (0) | 2025.02.23 |
| 왜 접속이 되지 않는걸까요.. 나의 작은 타임리프 (1) | 2025.02.22 |
| 뜬금없이 발생한 Too Many Connection (0) | 2025.02.22 |
| [Error] QueryExecutionRequestException : Not supported for DML operations (0) | 2023.01.14 |