즉시 로딩과 지연 로딩

2023. 7. 31. 12:09JPA

반응형

즉시 로딩

즉시 로딩(Eager Loading)을 사용하려면 @ManyToOne의 fetch 속성을 FetchType.EAGER로 지정한다.

// 즉시 로딩 설정
@Entity
public class Member {
   ...
   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "TEAM_ID")
   private Team team;
   ...
}

위의 코드에서 회원과 팀을 즉시 로딩으로 설정했다. 

// 즉시 로딩 실행 코드
Member member = em.find(Member.class, "member1");
Team team = member.getTeam(); //객체 그래프 탐색

따라서 em.find(Member.class, "member1")로 회원을 조회하는 순간 팀도 함께 조회한다. 이때 회원과 팀 두 테이블을 조회해야 하므로 쿼리를 두번 실행할 것 같지만, 대부분의 JPA구현체는 즉시 로딩을 최적화하기 위해 가능하면 조인 쿼리를 사용한다. 여기서는 회원과 팀을 조인해서 쿼리 한 번으로 두 엔티티를 모두 조회한다.

즉시 로딩

이후 member.getTeam()을 호출하면 이미 로딩된 team1 엔티티를 반환한다.

cf) 즉시 로딩 실행시 JPA에서는 외부 조인을 사용한다. 그 이유는 현재 회원 테이블에 TEAM_ID 외래 키는 NULL 값을 허용하고 있기 때문인데, 팀에 소속되지 않은 회원이 있을 가능성이 있다는 것이다. 팀에 소속하지 않은 회원과 팀을 내부 조인하면 팀은 물론이고 회원 데이터도 조회할 수 없다. 하지만 외부 조인보다 내부 조인이 성능과 최적화에서 더 유리하다. 내부 조인을 사용하려면 외래키에 NOT NULL 제약조건을 설정하면된다. JPA에게도 이 사실을 알려야하는데, @JoinColumn에 nullable = false 를 설정하면 된다. 그럼 JPA는 외부 조인 대신에 내부 조인을 사용한다. 참고로 @ManyToOne.optional 속성을 false로 지정해도 내부 조인을 사용한다. (optional = true : 외래키 null 허용, optional = false : 외래키 null 허용안함)

지연 로딩

지연 로딩(Lazy Loading)을 사용하려면 @ManyToOne의 fetch 속성을 FetchType.LAZY로 지정한다.

// 지연 로딩 설정
@Entity
public class Member {
   ...
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "TEAM_ID")
   private Team team;
   ...
}

위 코드를 보면 회원과 팀을 지연로딩으로 설정했다.

// 지연 로딩 실행 코드
Member member = em.find(Member.class, "member1");
Team team = member.getTeam(); //객체 그래프 탐색
team.getName(); //팀 객체 실제 사용

따라서 em.find(Member.class, "member1")을 호출하면 회원만 조회하고 팀은 조회하지 않는다.

지연 로딩

대신에 그림과 같이 조회한 회원의 team 멤버변수에 프록시 객체를 넣어둔다.

Team team = member.getTeam(); //프록시 객체

반환된 팀 객체는 프록시 객체다. 이 프록시 객체는 실제 사용될 때까지 데이터 로딩을 미룬다. 

team.getTeam(); //팀 객체 실제 사용

이처럼 실제 데이터가 필요한 순간이 되어서야 데이터베이스를 조회해서 프록시 객체를 초기화한다.

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

<FetchType.EAGER 설정과 조인 전략 정리>
▼ @ManyToOne, @OneToMany
→ (optional = false): 내부 조인
→ (optional = true): 외부 조인

▼ @OneToMany, @ManyToMany
→ (optional = false): 외부 조인
→ (optional = true): 외부 조인

반응형

'JPA' 카테고리의 다른 글

값 타입  (0) 2023.09.22
영속성 전이: CASCADE  (0) 2023.07.31
프록시  (0) 2023.07.28
@SecondaryTable : 엔티티 하나에 여러 테이블 매핑  (0) 2023.06.13
조인 테이블  (2) 2023.06.13