Replies: 1 comment 1 reply
-
fetch join은 한번의 쿼리로 연관된 엔티티를 한꺼번에 가져온다. JPA에서는 페이징을 제공해주는데, setFirstResult()와 setMaxResults() 메서드로 데이터베이스의 특정 부분만 가져올 수 있게 해준다. xxToOne 관계에서 fetch join과 페이징을 사용하는 것은 테이블을 조인해도 데이터의 수가 변하지 않기 때문에 문제되지 않는다. 하지만, xxToMany 관계에서는 테이블을 조인하면 데이터의 수가 변한다. 왜냐하면 카테시안 곱이 발생하여 데이터를 중복되게 가져오기 때문이다. (Order 하나에 여러 개의 Item이 매핑되어 있을 경우, Order가 중복된다.) 페이징은 보통 데이터베이스에서 limit과 offset으로 처리되는데, 스프링에서는 전체 데이터를 메모리에 로드한 후 중복을 없애고 offset과 limit을 적용해서 페이징을 시도한다. 그래도 결과적으로는 페이징이 되지 않는다. 데이터베이스 레벨에서 페이징을 하는 것이 아니기 떄문에 성능 저하 문제도 있고, 쿼리 단계에서 페이징이 적용되지 않으므로 반환 결과가 실제 페이징과 일치하지 않을 수 있다. 따라서, fetch join과 페이징을 함께 사용하기 위해서는 xxToOne 관계를 사용하거나, 배치 사이즈를 설정하여 해결할 수 있다. application 글로벌 설정에서 hibernate의 default_batch_fetch_size 옵션을 적용한다. 그러면 주요 엔티티 수만큼 참조객체를 불러오는 쿼리를 날리는 대신 hibernate가 1번 과정에서 불러온 주요 엔티티와 관련된 모든 toMany 참조객체를 in쿼리를 사용하여 한 번에 불러오게 된다. |
Beta Was this translation helpful? Give feedback.
-
.
Beta Was this translation helpful? Give feedback.
All reactions