3. Eager, Lazy Loading
- Spring Data JPA에 @ManyToOne(N : 1)으로 연관관계가 설정되어 있는 2개의 Entity가 존재할 때, DB는 join이 필요함
- @ManyToOne의 경우, FK 쪽의 Entity를 가져올 때, PK 쪽 Entity도 가져오게 되는데, 실무에서는 서비스의 규모가 대부분 크리 때문에 연관된 데이터를 한 번에 가져오는 행동은 부담이 큼
- JPA는 참조하는 데이터를 가져오는 시점을 정할 수 있는데, 이것을 Fetch Type이라고 함
Fetch Type
: JPA가 하나의 Entity를 조회할 때, 연관 관계에 있는 개체들을 어떻게 가져올 것이냐를 나타내는 설정값
- JPA에서는 JPQL을 이용하여 쿼리문을 생성하기 때문에 객체와 필드를 보고 쿼리를 작성함
- 다른 객체와 연관관계 매핑이 되어있으면, 그 객체들까지 조회하게 되는데, 이때 이 객체를 어떻게 불러올 것인가를 설정할 수 있음
Eager Loading(즉시 로딩)
: 특정 엔터티를 조회할 때, 연관된 모든 엔터티를 join을 통해 함께 조회하는 방식
- 엔터티 A조회시 관련되어 있는 엔터티 B를 같이 가져옴
- 실제 엔터티를 매핑함
- join을 사용하여 한 번에 가져옴 (즉시 로딩은 항상 외부 조인을 사용함)
- 장점 )
- 지연된 초기화와 관련해서 성능적인 영향이 없음
- 연관된 엔터티를 모두 가져올 수 있음
- 단점 )
- 지연 로딩보다 긴 초기의 로딩 시간이 필요
- 불필요한 데이터를 많이 로딩하면 성능에 영향을 줄 수 있음
- JPQL에서는 N + 1 문제를 일으킴
Lazy Loading(지연 로딩)
: 자신과 연관된 엔터티를 실제로 사용할 때 연관된 엔터티를 조회하는 방식
- 엔터티 A를 조회시, 관련되어 있는 엔터이 B를 가져오지 않음
- 프록시 매핑을 하고 실제 B를 조회할 때 뭐리가 나감
- 쿼리가 2번 나감 (A 조회시 한 번 + B 조회시 한 번)
- 프록시 : 실제 객체의 상속본
- 지연 로딩을 하면 연결된 다른 엔터티의 값을 가져올 수 없음
- 이러한 문제를 해결하기 위해서는 DB와의 재연결이 필요한데, @Transactional 어노테이션을 통해 해결할 수 있음
- @Transactional : 해당 메소드를 하나의 트랜잭션으로 처리하라는 의미
- 트랜잭션으로 처리하면 속성에 따라 다르게 동작하지만, 기본적으로는 필요할 때 다시 DB와의 연결이 생성되기 때문에 정상적으로 실행이 됨
- 장점 )
- 다른 접근 방식보다 훨씬 적은 초기의 로딩 시간
- 다른 접근 방식에 비해 메모리 소비량 감소
- 요청된 경우에만 사용자에게 콘텐츠를 제공하여 대역폭을 절약
- 단점 )
- 초기화가 지연되면 원하지 않는 순간 성능에 영향을 줄 수 있음
- DB와 연결된 Connection이 없다는 오류가 나타날 수 있음 -> 커넥션에 커밋을 날리고 트랜잭션이 닫힌 것을 의미