티스토리 뷰
앞서 프록시에 대해서 알아보았다.
프록시 객체는 지연로딩 시 사용한다고 했는데 지연 로딩은 무엇이고 또 다른 전략인 즉시 로딩이 무엇인지 한번 알아보자.
member1이 team1에 소속해 있다고 가정해보자.
Member member = em.find(Member.class, "member1");
Team team = member.getTeam(); //객체 그래프 탐색
System.out.println(team.getName()); //팀 엔티티 사용
회원 엔티티를 조회할 때 연관된 팀 엔티티도 함께 데이터베이스에서 조회하는 것이 좋을까?
아니면 회원 엔티티만 조회해 두고 팀 엔티티는 실제 사용하는 시점에 데이터베이스에서 조회하는 것이 좋을가?
JPA는 개발자가 연관된 엔티티의 조회 시점을 선택할 수 있도록 다음 두 가지 방법을 제공한다.
즉시 로딩
엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
하이버네이트는 가능하면 SQL 조인을 사용해서 한번에 조회한다.
예) em.find(Member.class, "member1")을 호출할 때 회원 엔티티와 연관된 팀 엔티티도 함께 조회한다.
사용 방법
@Entity
public class Member {
//..
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
//..
}
//즉시로딩 실행 코드
public void find() {
Member member = em.find(Member.class, "member1"); //회원을 조회하는 순간 팀도 함께 조회됨.
Team team = member.getTeam(); //객체 그래프 탐색
}
회원과 팀 두 테이블을 조회해야 하므로 쿼리를 2번 실행할 것 같지만 !!!
대부분의 JPA 구현체는 즉시 로딩을 최적화하기 위해 가능하면 조인 쿼리를 사용한다.
지연 로딩
연관된 엔티티를 실제 사용할 때 조회한다.
즉, 처음에 연관된 엔티티를 프록시로 조회하고 프록시를 실제 사용할 때 초기화하면서 데이터베이스를 조회한다.
예) member.getTeam().getName() 처럼 조회한 팀 엔티티를 실제 사용하는 시점에 JPA가 SQL을 호출해서 팀 엔티티를 조회한다.
사용 방법
@Entity
public class Member {
//..
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
//..
}
//지연로딩 실행 코드
public void find() {
Member member = em.find(Member.class, "member1"); //회원만 조회하고 팀은 조회하지 않음
Team team = member.getTeam(); //객체 그래프 탐색 -> 프록시 객체
team.getName(); //팀 객체 실제 사용
}
회원의 team 멤버 변수에 프록시 객체를 넣어둔다.
반환된 팀 객체는 프록시 객체이다. 이 프록시 객체는 실제 사용될 때까지 데이터 로딩을 미룬다. 그래서 지연 로딩이라고 한다.
* 참고 내용 *
조회 대상이 영속성 컨텍스트에 이미 있으면 프록시 객체를 사용할 이유가 없다.
따라서 프록시가 아닌 실제 객체를 사용한다.
예를들어 team1 엔티티가 영속성 컨텍스트에 이미 로딩되어 있으면
프록시가 아닌 실제 team1 엔티티를 사용한다.
Fetch 전략
연관된 엔티티가 하나면 즉시 로딩을, 컬렉션이면 지연 로딩을 사용한다.
컬렉션을 로딩하는 것은 비용이 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문이다.
만약 한 회원의 연관된 컬렉션에 수만 건의 데이터가 있을 때, 즉시로딩을 설정했다고 가정해보자.
해당 회원을 조회하면 연관된 수만건의 데이터가 함께 조회될 것이다.
따라서 지연 로딩을 권장한다.
.
.
음. 이 책에서는 모든 연관관계에 지연 로딩을 사용하고, 애플리케이션 개발이 완료단계에 있을 때 실제 사용하는 상황을 보고 꼭 필요한 곳에만 즉시 로딩을 사용하도록 최적화하라고 되어있다 !
.
.
끝.
참고
자바 ORM 표준 JPA 프로그래밍 - 김영한
'Framework > Spring' 카테고리의 다른 글
[Spring] 순환 참조 (0) | 2022.12.13 |
---|---|
[JPA] N + 1 문제 (0) | 2022.12.05 |
[JPA] 프록시 객체 (0) | 2022.10.31 |
[JPA] 양방향 연관관계 매핑 (0) | 2022.10.26 |
[JPA] 플러시 (0) | 2022.10.25 |
- Total
- Today
- Yesterday
- Red-Black Tree
- Caching
- 다중화
- 자동구성
- syncronized
- nosql
- 티스토리챌린지
- java
- Security
- @conditional
- AutoConfiguration
- 정적변수
- fail-fast
- spring boot
- Spring
- Hash
- 인스턴스변수
- object
- Load Balancer
- fail-safe
- Sticky Session
- 고정 세션
- 오블완
- nginx
- 추상클래스
- 로드 밸런서
- 인터페이스
- JPA
- HashSet
- HashMap
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |