작성
·
683
0
안녕하세요. JPA 강의를 듣고 프로젝트를 진행하던중에 페치조인과 관련된 문제가 생겨서 질문드립니다.
총 4개의 엔티티(A,B,C,D)가 있습니다.
B는 각각 A, C와 ManyToOne 관계입니다.
* A(1) <- B(N) -> C(1)
C는 D와 ManyToOne 관계입니다.
* C(N) -> D(1)
이런 상황에서 JPQL로 B를 조회하려합니다. 상세 조건은 아래와 같습니다.
B를 조회하면서 C를 페치조인으로 같이 가져오고 싶습니다. (A는 가져오지 않음)
조회 조건은 A의 id 값과 D의 id 값입니다.
위의 조회를 위해서 JPQL을 다음과 같이 짜보았습니다.
1. select b from B b join fetch b.c where b.a.id = :a_Id and b.c.d.id = :d_Id
2. select b from B b join fetch b.c c where b.a.id = :a_Id and c.d.id = :d_Id
JPA의 표준 스펙상 페치조인의 대상에는 별칭을 줄 수 없다고 하셔서 별칭을 주지 않고 작성한 것이 1, Hibernate에서 별칭을 허용하기 때문에 별칭을 주고 작성한 것이 2입니다.
그런데 위의 두 JPQL 모두 애플리케이션 로딩시점에서 아예 예외가 터져버리더라구요.
SemanticException: query specified join fetching, but the owner of the fetched association was not present in the select list
위에 적어놓은 것과 같이 ManyToOne 관계가 연쇄적으로 걸려있는 상황에서 페치조인을 어떻게 해야하는지 궁금합니다.
답변 1
1
안녕하세요. 세승님
D에 대한 id를 WHERE 문장에서 사용하려면 조인을 추가하시면 됩니다.
다음 코드를 참고해주세요.
SELECT b
FROM B b
JOIN FETCH b.c c
JOIN c.d d
WHERE b.a.id = :aId AND d.id = :dId
감사합니다.
안녕하세요. 세승님
별칭문제의 경우 단순히 조회 용도로만 사용한다면 특별히 문제가 되지는 않습니다.
자세한 내용은 다음을 참고해주세요
컬렉션이 아닌 ManyToOne 관계는 얼마든지 페치조인을 할 수 있습니다.(활용2편에서 설명)
감사합니다.
빠른 답글 감사합니다 영한님!
위와 같은 경우에 페치조인의 대상에 별칭을 붙이게 되는데, 별칭을 붙이므로써 생기는 문제는 없을까요?
+ 컬렉션을 페치조인하는 상황에서는 페이징이 불가능했었는데, 컬렉션이 아닌 ManyToOne 관계에서 단일 엔티티를 페치조인 할때도 페이징이 불가능한가요?
추가.
영한님이 작성해주신 JPQL을 살짝 수정해서 돌려보았는데, 기존에 있었던 JOIN c.d d 를 없애고, d.id 대신 c.d.id 를 사용했습니다.
엔티티 C(N)와 D(1)가 다대일 관계이기 때문에, C의 DB 테이블에 D의 PK값이 FK로 존재하고 있어서, 굳이 D엔티티를 추가적으로 JOIN 할 필요가 없었던 것 같습니다.
혹시 제가 잘못 생각한게 있다면 답글 부탁드립니다!