1. 즉시 로딩
1) 즉시 로딩 기법이란?
- JOIN으로 한 번에 연관된 객체까지 미리 조회하는 방법
- @ManyToOne(fetch=FetchType.EAGER) 으로 설정한다.
2) JOIN 방식
- 즉시 로딩에서는 기본적으로 LEFT OUTER JOIN을 이용하여 조인한다. 그 이유는 외래 키가 NULL일 위험성 때문인데, 외래 키가 NULL이면 현재 엔티티도 조회되지 않는다.
- 엔티티의 외래 키에 다음과 같이 NOT NULL을 설정하면 JPA는 외부 조인 대신에 내부 조인을 사용한다.
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(... , nullable=false)
private Team team;
또는 optional 옵션으로 지정할 수도 있다.
- @ManyToOne : optional을 true로 지정하면 외부조인, false로 지정하면 내부 조인
- @OneToOne : optional을 true로 지정하면 외부조인, false로 지정하면 내부 조인
- @OneToMany : optional값에 관계 없이 외부 조인
- @ManyToMany : optional값에 관계 없이 외부 조인
3) 컬렉션 즉시 로딩 사용 시 주의할 점
- 컬렉션을 즉시 로딩하는 것은 비용이 많이 든다. 특히 서로 다른 2개 이상의 컬렉션(N:M)을 즉시 로딩하는 것은 자제하자.
- 컬렉션을 즉시 로딩하는 경우에는 항상 외부 조인을 사용해야 한다. 컬렉션에 아무 값도 없다면 현재 엔티티도 조회되지 않는다.
2. 지연 로딩
1) 지연 로딩 기법이란?
- 객체가 실제 사용될 때 로딩하는 방법
- @ManyToOne(fetch=FetchType.LAZY) 으로 설정한다.
2) 지연 로딩과 프록시
- 엔티티를 조회하게 되면 지연 로딩이 적용된 연관 객체에는 프록시 객체가 대신 저장된다. 프록시 객체에 대한 설명은 아래 포스팅을 참고하자.
https://kimcoder.tistory.com/487
- 조회 대상이 이미 영속성 컨텍스트에 존재하면 프록시가 아닌 실제 객체를 반환한다.
3) 컬렉션 래퍼
- 연관 엔티티를 지연 로딩할 때는 프록시 객체를 사용하지만, List 같은 컬렉션은 컬렉션 래퍼가 지연 로딩을 처리해준다.
- 컬렉션 래퍼는 org.hibernate.collection.internal.PersistentBag 클래스다.
- 컬렉션 자체를 호출 할 때는 컬렉션이 초기화되지 않고, 컬렉션에서 실제 데이터를 조회할 때 초기화한다.
team.getMembers() // 컬렉션 초기화 X
team.getMembers().get(0) // 컬렉션 초기화 O
3. Fetch 전략
- 엔티티와 연관 엔티티가 자주 함께 사용된다면 즉시 로딩으로 설정하고, 가끔만 사용된다면 지연 로딩으로 설정하는 것이 성능상 유리하다.
- JPA가 제공하는 연관관계 매핑 어노테이션별 fetch 속성의 기본값은 다음과 같다. 기본적으로 연관 엔티티가 하나면 즉시 로딩을 사용하고 컬렉션이면 지연 로딩을 사용한다.
- @ManyToOne : FetchType.EAGER
- @OneToOne : FetchType.EAGER
- @OneToMany : FetchType.LAZY
- @ManyToMany : FetchType.LAZY
- 가장 추천하는 전략은 모든 연관관계에 지연 로딩을 사용하고, 꼭 필요한 곳에만 즉시 로딩을 적용하는 식으로 최적화하는 것이다.★
● 참고자료 : 자바 ORM 표준 JPA 프로그래밍
'Spring 사전 준비 > JPA Hibernate' 카테고리의 다른 글
[JPA] 복합 값 타입과 불변 객체 (0) | 2022.08.03 |
---|---|
[JPA] CASCADE 기능 (0) | 2022.08.03 |
[JPA] 프록시 객체 (0) | 2022.08.01 |
[JPA] 고급 매핑 기술 (0) | 2022.07.28 |
[JPA] 일대일 매핑과 다대다 매핑 (0) | 2022.07.26 |
댓글