즉시로딩과 지연로딩

양성빈·2022년 4월 17일
1

참고

Member를 조회할 때 Team도 함께 조회해야 할까?

  • 단순히 member 정보만 사용하는 비즈니스 로직
    println(member.getName());

지연 로딩 LAZY을 사용해서 프록시로 조회

@Entity
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;
 }

  • Member member = em.find(Member.class, 1L);

  • Team team = member.getTeam();
  • team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회)

즉시 로딩 EAGER를 사용해서 함께 조회

@Entity
public class Member extends BaseEntity {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

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

    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}

즉시 로딩(EAGER), Member조회시 항상 Team도 조회

  • JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회

프록시와 즉시로딩 주의

  • 가급적 지연 로딩만 사용(특히 실무에서)
  • 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
  • @ManyToOne, @OneToOne은 기본이 즉시 로딩
    -> LAZY로 설정
  • @OneToMany, @ManyToMany는 기본이 지연 로딩

지연 로딩 활용

  • Member와 Team은 자주 함께 사용 -> 즉시 로딩
  • Member와 Order는 가끔 사용 -> 지연 로딩
  • Order와 Product는 자주 함께 사용 -> 즉시 로딩

실무

  • 모든 연관관계에 지연 로딩을 사용해라!
  • 실무에서 즉시 로딩을 사용하지 마라!
  • JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라! (뒤에서 설명)
  • 즉시 로딩은 상상하지 못한 쿼리가 나간다.
profile
모든 것을 즐길줄 아는 개발자입니다!

0개의 댓글

관련 채용 정보