Close
Close full mode
logo만렙 개발자 키우기

(3) 지연로딩 활용

Git RepositoryEdit on Github
Last update: a year ago by nowwaterReading time: 2 min

8.3.1 프록시와 컬렉션 래퍼

하이버네이트는 엔티티를 영속 상태로 만들 때 엔티티에 컬렉션이 있으면 컬렉션을 추적하고 관리할 목적으로 원본 컬렉션을 하이버네이트가 제공하는 내장 컬렉션으로 변경하는데, 이를 컬렉션 래퍼 라고 한다.

이러한 컬렉션 래퍼가 컬렉션에 대해 지연 로딩을 처리해준다.

참고로 member.getOrders() 를 호출해도 컬렉션은 초기화되지 않는다.
`member.getOrders().get(0)' 처럼 컬렉션에서 실제 데이터를 조회할 때 데이터베이스를 조회해서 초기화하기 때문이다.

내장 컬렉션 : org.hibernate.collection.internal.PersistentBag


8.3.2 JPA 기본 페치 전략

fetch 속성의 기본 설정값

  • @ManyToOne, @OneToOne : 즉시 로딩(FetchType.EAGER)
  • @OneToMany, @ManyToMany : 지연 로딩(FetchType.LAZY

연관된 엔티티가 하나면 즉시 로딩, 컬렉션이면 지연 로딩을 사용한다.

컬렉션을 로딩하는 것은 비용이 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문이다.

모든 연관관계에 지연 로딩을 사용하는 것을 추천한다.

그리고 애플리케이션 개발이 어느 정도 완료단계에 왔을 때 실제 사용하는 상황을 보고 꼭 필요한 곳에만 즉시 로딩을 사용하도록 최적화하면 된다.

SQL을 직접 사용하면 이런 유연한 최적화가 어렵다. ex) SQL로 각각의 테이블 조회해서 처리하다가 조인으로 한 번에 조회하도록 변경하려면 많은 SQL과 애플리케이션 코드 수정..

컬렉션에 FetchType.EAGER 사용 시 주의점

  • 컬렉션을 하나 이상 즉시 로딩하는 것은 권장하지 않는다.

    • 컬렉션과 조인한다는 것은 데이터베이스 테이블로 보면 일대다 조인이다.

    • 일대다 조인은 결과 데이터가 다 쪽에 있는 수만큼 증가하게 된다.

    • 서로 다른 컬렉션을 2개 이상(예를 들어 N, M 테이블) 조인하면 SQL 실행 결과가 N * M 이 되면서 너무 많은 데이터를 반환하여 애플리케이션 성능 저하

  • 컬렉션 즉시 로딩은 항상 외부 조인을 사용한다.

    • 예를 들어, 회원과 팀은 다대일 관계.

    • 이 둘을 조인할 때 회원 테이블의 외래 키에 not null 제약조건을 걸어두면 모든 회원은 팀에 소속되므로 항상 내부 조인 사용 가능

    • 하지만 팀에서 회원으로 일대다 관계 조인 시 회원이 한 명도 없는 팀을 내부 조인하면 팀까지 조회되지 않는다.

  • @ManyToOne, @OneToOne

    • (optional = false) : 내부 조인

    • (optional = true) : 외부 조인

  • @OneToMany, @ManyToMany

    • (optional = false) : 외부 조인

    • (optional = true) : 내부 조인

🚀 JPA — Previous
(2) 즉시로딩과 지연로딩
Next — 🚀 JPA
(4) 영속성 전이_CASCADE