FOREST_CHOI's BLOG

Querydsl의 FetchJoin 과 DTO 본문

프로그래밍/JPA

Querydsl의 FetchJoin 과 DTO

Forest_Choi 2022. 12. 22. 08:44
728x90

Querydsl을 사용하면서 fetchjoin을 하고 있는데 처음 보는 오류가 발생했다.

 

Caused by: org.hibernate.QueryException: query specified join fetching,
but the owner of the fetched association was not present in the select list 
[FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,

일단 그냥 직관적으로 봤을땐 join할 때 fetch해오면서 어떠한 문제가 생기는 것이었다.

 

	queryFactory.select(Projections.constructor(RelationMemberDto.class,
                        relation.friend.id.as("friendId"),
                        relation.friend.name.as("friendName"),
                        relation.friend.profileImage.as("friendProfileImage")
                ))
                .from(relation)
                .join(relation.friend, member).fetchJoin()
                .where(
                        memberIdEq(memberId),
                        relationTypeEq(condition.getStatus()),
                        nameEq(condition.getName()),
                        emailEq(condition.getEmail())
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

이는 처음에 작성하였던 쿼리문이다.

 

관련해서 문제를 찾아보니, 내가 FetchJoin 자체를 잘못 사용하고 있었다.

 

FetchJoin을 사용하는 이유는, Entity에서 EntityGraph를 참조하는데 사용하는 것이기 때문에 Entity를 조회해야한다.

DTO를 조회하는 일은 불가능 한 것이었다.

 

나처럼 Entity를 가져오는 것이 아닌, 별도 DTO로 가져오고 싶다면 FetchJoin이 아닌 그냥 Join을 사용하면 될것이다.

 

아래는 수정 된 코드이다.

join(relation.friend, member).fetchJoin() -> leftJoin(relation.friend, member) 로 수정하였따.

 

	queryFactory.select(Projections.constructor(RelationMemberDto.class,
                        relation.friend.id.as("friendId"),
                        relation.friend.name.as("friendName"),
                        relation.friend.profileImage.as("friendProfileImage")
                ))
                .from(relation)
                .leftJoin(relation.friend, member)
                .where(
                        memberIdEq(memberId),
                        relationTypeEq(condition.getStatus()),
                        nameEq(condition.getName()),
                        emailEq(condition.getEmail())
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
728x90
Comments