JPA 일대다(OneToMany) 관계 처리 방법
1. 페치 조인
특징
- 한 번의 쿼리로 연관된 엔티티를 모두 조회
- 일대다 페치 조인은 하나만 사용 가능 (데이터 정합성 문제)
- 페이징과 함께 사용하면 메모리에서 페이징 처리 (성능 이슈)
예시 코드
.leftJoin(question.answerList).fetchJoin()
2. 배치 사이즈
특징
- 지연 로딩 시 IN 쿼리를 통해 N+1 문제 해결
- 설정한 배치 사이즈만큼 IN 쿼리로 한 번에 조회
- 페이징과 함께 사용 가능 (실제 DB에서 페이징)
- 네트워크 통신 횟수 감소
설정 방법
// 엔티티에 직접 설정
@BatchSize(size = 100)
private List<Answer> answerList;
// 또는 application.yml에 글로벌 설정
spring:
jpa:
properties:
hibernate:
default_batch_fetch_size: 100
3. 별도 쿼리로 처리
특징
- 메인 엔티티와 연관 엔티티를 각각 조회
- 페이징을 DB에서 처리 가능
- 필요한 데이터만 조회 가능
- 쿼리 최적화가 용이
예시 코드
// 메인 엔티티 조회
Question question = queryFactory
.selectFrom(question)
.where(question.id.eq(id))
.fetchOne();
// 연관 엔티티 별도 조회 (페이징 가능)
List<Answer> answers = queryFactory
.selectFrom(answer)
.where(answer.question.id.eq(id))
.offset(pageNum * pageSize)
.limit(pageSize)
.fetch();
댓글