즉시 로딩과 지연 로딩
프록시 객체는 주로 연관된 엔티티를 지연 로딩 할 때 사용한다.
Member member = em.find( Member.class, "binsoo" )
- 객체 그래프 탐색
Team ream = member.getTeam()
- 팀 엔티티 사용
team.getName()
회원 엔티티를 조회할 때 연관된 팀 엔티티도 함께 DB 에서 조회하는 것이 좋을까 ?
아니면 회원 엔티티만 조회해두고 팀 엔티티는 실제 사용하는 시점에 DB 에서 조회하는 것이 좋을까 ?
- 즉시 로딩 - EAGER LOADING
- 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
- 하이버네이트는 가능하면 SQL 조인을 사용해서 한 번에 조회한다.
- 설정 방법
- @ManyToOne( fetch = FetchType.EAGER )
- 지연 로딩 - LAZY LOADING
- 연관된 엔티티를 실제 사용할 때 조회한다.
- 연관된 엔티티를 프록시로 조회한다. 프록시를 실제 사용할 때 초기화 하면서 DB 를 조회한다.
- 설정 방법
- @ManyToOne( fetch = FetchType.LAZY)
처음부터 연관된 엔티티를 모두 영속성 컨텍스트에 올려두는 것은 현실적이지 않고,
필요할 때마다 SQL 을 실행시켜 연관된 엔티티를 지연 로딩 하는 것도 퇴적화 관점에서 보면 꼭 좋은 것은 아니다.
예를 들어서 대부분의 애플리케이션 로직에서 회원과 팀 엔티티를 같이 사용한다면
SQL 조인을 사용해서 회원과 팀 엔티티를 한번에 조회하는 것이 효율적이다.
결국 연관된 엔티티를 즉시 로딩하는 것이 좋은지는 상황에 따라 다르다.
JPA 의 기본 패치 전략
- @ManyToOne / @OneToOne
- 즉시 로딩
- @OneToMany / @ManyToMany
- 지연 로딩
JPA 의 기본 패치 전략은 연관된 엔티티가 하나면 즉시 로딩을, 컬렉션이면 지연 로딩을 사용한다.
컬렉션을 로딩하는 것은 비용이 너무 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문이다.
예를 들어 특정 회원이 연관된 컬렉션에 데이터를 수만건 등록 했는데
설정한 패티 전략이 즉시 로딩이면 해당 회원을 로딩하는 순간 수만건의 데이터도 함께 로딩이 된다.
반면에 연관된 엔티티가 하나면 즉시 로딩해도 큰 문제가 발생하지 않는다.
추천하는 방법은 모든 연관관계에 자연 로딩을 사용하는 것이다.
그리고 애플리케이션 개발이 어느 정도 완료 단계에 있을 때 실제 사용하는 상황을 보고
꼭 필요한 곳에만 즉시 로딩을 사용하도록 최적화 하면 된다.
참고로 SQL 문을 직접 사용하면 이런 유연한 최적화가 어렵다.
예를 들어 SQL 로 각각의 테이블을 조회해서 처리하다가 조인으로 한번에 조회하도록 변경하면
많은 SQL 과 애플리케이션 코드를 수정해야 한다.
'개발중 > Java Persistence API (JPA)' 카테고리의 다른 글
Java 객체/ 기본값 타입의 특징 (0) | 2021.06.30 |
---|---|
JPA - 값 타입 컬렉션 (0) | 2021.06.30 |
JPA / 프록시 알아보기 (0) | 2021.06.28 |
식별 관계와 비식별 관계 구분 (0) | 2021.06.25 |
JPA - 어노테이션 정리 (0) | 2021.06.25 |