Repository 테스트 코드를 작성하던 중 EntityGraph와 fetch join에서 예상치 못한 동작이 발생하여 글을 작성하게 되었습니다.
결론적으로 EntityGraph의 경우 fetchType을 eager로 변환하는 방식으로 outer left join을 수행하여 데이터를 가져오지만, fetch join의 경우 따로 outer join으로 명시하지 않는 경우 inner join을 수행한다는 점입니다.
이 때문에 fetch join의 단점을 피할 수 있습니다.(1:N 컬렉션 join시 하나만 join할 수 있는 제약, distinct사용)
이렇게 되는 이유는 EntityGraph의 경우 fetchType을 전환하여 조회하는 개념이기 때문입니다.이 이전에는 Spring Data JPA를 통해 fetch join 을 쿼리 없이 편리하게 작성하는 방법으로 오인하고 있었습니다.)
JPAQuery<Article> query = queryFactory.select(article).distinct()
.from(article)
.join(article.articleMembers, articleMember).fetchJoin()
.where(
isDeletedIsFalse(),
isComplete(condition.getIsComplete()),
isContentCategory(condition.getContentCategory()),
isAnonymity(condition.getAnonymity())
);
select ...
from
article article0_
inner join
article_member articlemem1_
on article0_.article_id=articlemem1_.article_id
where
article0_.is_deleted=?
order by
article0_.created_at asc
@EntityGraph(attributePaths = {"articleMatchConditions"})
Optional<Article> findDistinctFetchArticleMatchConditionsByApiIdAndIsDeletedIsFalse(String articleId);
from
article article0_
left outer join
article_match_condition articlemat1_
on article0_.article_id=articlemat1_.article_id
where
article0_.api_id=?
and article0_.is_deleted=0
https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/EntityGraph.html
https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/EntityGraph.EntityGraphType.html