queryDsl을 사용하던 중 query specified join fetching, but the owner of the fetched association was not present in the select list 에러가 발생하여 원인과 해결과정에 대해 정리하는 포스팅입니다.
1. error의 원인 코드
jpaQueryFactory
.select(mainPayment.itemImage, mainPayment.itemName, mainPayment.subPayment.pointUse)
.from(mainPayment)
.join(mainPayment.subPayment, subPayment)
.fetchJoin()
.fetchOne();
위의 코드를 살펴보면 subPayment를 join 한 후 N+1 문제를 해결하기 위해 fetchJoin()을 사용하고 있습니다. 하지만 어째서인지 위와 같은 에러가 발생하였습니다.
2. error의 원인
fetch join을 사용하면서 특정 부분의 column만을 요청하는 것은 hibernate에게 부분적으로 initialized된 entity를 달라고 하는 것과 같다고 합니다. 이에 대해 hibernate는 이를 막고 있다고 합니다. 왜냐하면 나중에 추가로 필요한 부분이 있을 때 query를 또 날려야 하는지, 에러를 던져야하는지 등에 대해 혼란스러워지는 문제가 존재하기 때문입니다.
3. error의 해결
1. fetch join을 사용하지 않는 방안 - N+1의 문제를 해결하기 위함이었는데, 이는 query를 여러개 나가지 않게 하기라는 목적을 달성할 수 없습니다.
2. Projection 사용하기
2.1 projection class를 구현합니다.
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PaymentCancelProjection {
private String itemImage;
private String itemName;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate travelStartDate; // 여행 시작 날짜
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate travelEndDate; // 여행 종료 날짜
private Integer pointUse; // 포인트 사용
private Integer itemPayPrice; //
}
2.2 쿼리를 작성합니다.
PaymentCancelProjection result = jpaQueryFactory
.select(Projections.constructor(PaymentCancelProjection.class,
mainPayment.itemImage,
mainPayment.itemName,
mainPayment.travelStartDate,
mainPayment.travelEndDate,
mainPayment.itemPayPrice,
subPayment.pointUse))
.from(mainPayment)
.join(mainPayment.subPayment, subPayment)
.where(mainPayment.id.eq(mainPaymentId))
.fetchOne();
'IT > 디버깅' 카테고리의 다른 글
jwt 사용 시 remember me 적용 안되는 이슈 (0) | 2024.01.25 |
---|---|
@WithMockUser 사용시 요청에 사용되는 User와 MockUser가 다른 경우 발생하는 에러 401 (0) | 2023.11.11 |
한진정보통신 인턴과제 - yolo8 FileNotFoundError: Image Not Found 이슈 해결 (0) | 2023.07.26 |
한진정보통신 인턴과제 - 구글 코랩 tensorflow light install 이슈 해결 (0) | 2023.07.20 |
[디버깅] bitbucket permission denied 오류 해결 (0) | 2023.04.26 |