본문 바로가기
JPA/JPA

[JPA] 즉시 로딩과 지연 로딩

by 걸어가는 신사 2022. 1. 3.

1. 즉시 로딩 (EAGER Loading)

엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.

즉시 로딩

@Entity
@Getter @Setter
public class Member {
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}
  • @ManyToOne (fetch = FetchType.EAGER) 지정함으로써 즉시 로딩 선언
//즉시 로딩
Member findMember = em.find(Member.class, member.getId());
Team team = findMember.getTeam(); //객체 그래프 탐색
  • em.find(Member.class, member.getId())을 호출할 때 회원 엔티티와 연관된 팀 엔티티도 함께 조회한다.
    • JPA 구현체는 즉시 로딩을 최적화하기 위해 가능하면 조인 쿼리를 사용한다.
위 예제를 실행해 보면 로딩 실행 SQL에서 JPA가 내부 조인(INNER JOIN)이 아닌 외부 조인(LEFT OUTER JOIN)을 사용하였다. (외부 조인보다 내부 조인이 성능과 최적화에서 더 유리하다)
(1) 외래 키에 NOT NULL 제약 조건을 설정하면 값이 있는 것을 보장한다 => 내부 조인 사용
@JoinColumn(nullable = false)
(2) @ManyToOne(fetch = FetchType.EAGER, optional = false)

 

2. 지연로딩 (LAZY Loading)

연관된 엔티티를 실제 사용할 때 조회한다.

지연 로딩

@Entity
@Getter @Setter
public class Member extends BaseEntity{
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String name;

    @ManyToOne(fetch = FetchType.LAZY) //프록시객체로 조회한다.
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}
  • @ManyToOne(fetch = FetchType.LAZY) 으로 지연 로딩 선언
//지연로딩
Member findMember = em.find(Member.class, member.getId());
Team team = member.getTeam(); //프록시 객체
team.getName(); //프록시 초기화가 일어난다.
  • em.find(Member.class, member.getId())를 호출하면 회원만 조회하고 팀은 조회하지 않는다.

 

3. 프록시와 즉시 로딩 주의

  • 모든 연관관계에서 지연 로딩만 사용하자.
    • 실무에서는 절대 즉시 로딩을 사용하지 마라!
    • JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해서 해결하자.
  • 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생한다.
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
  • @ManyToOne, @OneToOne은 default가 즉시 로딩이다. => 지연 로딩으로 바꿔주어야 한다.
  • @OneToMany, @ManyToMany는 기본이 지연 로딩이다.
반응형

'JPA > JPA' 카테고리의 다른 글

[JPA] 값 타입  (0) 2022.01.04
[JPA] 영속성 전이(CASCADE)와 고아 객체 제거  (0) 2022.01.03
[JPA] 프록시 (Proxy)  (0) 2022.01.03
[JPA] @MappedSuperclass  (0) 2022.01.03
[JPA] 상속 관계 매핑  (0) 2022.01.03

댓글