~/tech-blog/posts/jpa-lazy-eager-loading — zsh

즉시 로딩과 지연 로딩

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

이 물음에 JPA는 지연 로딩과 즉시 로딩이라는 두 가지 답을 마련해 두었습니다.

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

Java
@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
    private Team team;
  • em.find(Member.class, 1L)로 조회하면 멤버는 DB에서 조회한 후 영속성 컨텍스트에 저장됩니다. 이때 Team은 프록시(가짜 객체)로 참조값이 null인 상태로 들어갑니다.
  • 이후 team.getName()을 호출하는 시점에 해당하는 값을 DB에서 조회(초기화)한 후, 참조 값이 null이던 자리에 데이터를 채워 넣습니다.

즉시 로딩(EAGER)을 사용해서 함께 조회

Java
@Entity
public class Member extends BaseEntity {

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

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

    @ManyToOne(fetch = FetchType.EAGER)// 팀을 프록시로 조회한다.@JoinColumn
    private Team team;
  • 즉시 로딩으로 두면 Member를 조회할 때 Team도 항상 함께 조회됩니다.

프록시와 즉시 로딩 주의

  • 가급적 지연 로딩만 사용합니다(특히 실무에서).
  • 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생합니다.
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킵니다.
  • @ManyToOne, @OneToOne은 기본이 즉시 로딩입니다. LAZY로 바꿔 두어야 합니다.
  • @OneToMany, @ManyToMany는 기본이 지연 로딩입니다.

지연 로딩 활용 - 실무

  • 모든 연관관계에 지연 로딩을 사용하세요!
  • 실무에서 즉시 로딩을 사용하지 마세요!
  • JPQL 페치 조인이나, 엔티티 그래프 기능을 사용하세요!
  • 즉시 로딩은 상상하지 못한 쿼리가 나갑니다.

이 글은 인프런 김영한 님의 자바 ORM 표준 JPA 프로그래밍 — 기본편을 들으며 정리한 노트입니다.

댓글

GitHub 계정으로 로그인하시면 댓글과 질문을 남기실 수 있습니다. 남겨 주신 글은 이 저장소의 Discussions에 쌓입니다.

● main 214 posts UTF-8 LF © 2026 코징 RSS · GitHub