fetch type
- Eager : 연관 관계에 있는 Entity 를 모두 가져온다
- Lazy : getter 로 접근할 때 Entity 를 가져온다.
N+1 문제
발생 상황
- Lazy 타입 사용시 로딩이 발생할 때 쿼리가 N번 추가 발생
해결방법
- JPQL 의 fetch join 이용
- 조회시 바로 가져오고 싶은 Entity 필드를 지정
/**
* 1. join fetch를 통한 조회
*/
@Query("select a from Academy a join fetch a.subjects")
List<Academy> findAllJoinFetch();
- ManyToOne, OneToMany 의 fetch type 을 Lazy 에서 Eager 로 변경
@ManyToOne(mappedBy = "owner", fetch = FetchType.Eager)
@EntityGraph
를 통해 EAGER load 지정
attributePaths
에 필드명을 지정하면 Lazy 대신 Eager 로 바로 가져옴
@EntityGraph(attributePaths = "subjects")
@Query("select a from Academy a")
List<Academy> findAllEntityGraph();
주의사항
- JoinFetch는
Inner Join
, Entity Graph는 Outer Join
- 둘 모두 카테시안 곱 발생 -> 중복 로딩되는 문제
- 해당 문제는 Set 을 사용하여 해결 가능
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="academy_id")
private Set<Subject> subjects = new LinkedHashSet<>();