도전할 수 있는 방법이 생각날 때마다 포스팅 업데이트...
필자는 부모 하나에 @OneToMany 자식 2개는 default_batch_fetch_size
를 설정해서 쿼리 한번에 가져올 수 있는 것으로 알고 있다. (자식 <- 부모 -> 자식)
그렇다면 부모 -> 자식 -> 손자로 @OneToMany가 두 번인 상황에서 쿼리 한 번에 가져올 수 있을까?
Member
: Post
= 1 : N
Post
: Comment
= 1 : M
인 상황이라면 세 엔티티의 관계는 1 : N : NM이다.
세 엔티티를 쿼리 한방에 모두 가져올 수 있을지 실험해보자.
TypedQuery<Member> query = em.createQuery("from Member", Member.class);
EntityGraph<Member> entityGraph = em.createEntityGraph(Member.class);
entityGraph.addAttributeNodes("posts");
entityGraph.addSubgraph("posts").addAttributeNodes("comments");
query.setHint("javax.persistence.fetchgraph", entityGraph);
위와 같이 EntityGraph를 만들어 한 번에 가져오고자 했다.
그냥 돌려보자.
org.hibernate.loader.MultipleBagFetchException
이 발생했다.
두 개 이상의 @OneToMany를 Fetch Join 시도할 때 발생하는 에러이다.
해결 방법은 Hibernate default_batch_fetch_size
를 설정하는 방법이다.
물론 우리는 부모 -> 자식 -> 손자의 상황이지만 혹시 모르니 시도해보자.
간단하게, yaml에서 spring.jpa.properties.hibernate.default_batch_fetch_size: 1000
을 넣어 준다.
다시 한번 시도해보면 결과는...?
batch size를 수정해도 똑같은 결과가 나왔다.
단순히 여러 @OneToMany를 Fetch Join으로 가져오는 것과 근본적으로 다른 문제라는 것을 확인했다.
결론적으로 이러한 상황에서는 영속성이 아닌, 연관된 엔티티 필드들을 DTO로 만들어 가져와야될 것 같다!