오봉이와 함께하는 개발 블로그

JPA - 즉시 로딩, 지연 로딩 본문

BE/JPA

JPA - 즉시 로딩, 지연 로딩

오봉봉이 2022. 6. 28. 21:54
728x90

즉시 로딩과 지연 로딩

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

일 때, 단순 member만 정보만 사용하는 비즈니스 로직이 있는데, Team의 정보를 사용하지 않을 수는 없을까?
그래서 JPA는 지연 로딩이라는 것을 지원한다

지연 로딩

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

위와 같이 사용할 수 있다.
지연 로딩을 사용하면 어떻게 되냐?

Member m = em.find(Member.class, member1.getId());

System.out.println("m = " + m.getTeam().getClass());
// 프록시 객체 출력

m.getTeam().getName();
// Team의 내부를 조회하는 시점에 프록시 객체가 초기화 되며 조회 쿼리 요청


즉시 로딩

Member와 Team을 자주 함께 사용할 때는 즉시 로딩을 사용하면 된다.

@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.EAGER)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}


즉시 로딩을 사용하면 Member를 조회할 때 Team도 Join을 통해 같이 조회를 하고, 프록시 객체가 아닌 진짜 객체를 가져온다.

프록시와 즉시 로딩 주의

1개 ~ 2개 테이블을 조인 한다면 큰 문제가 되지 않겠지만 연결된 수십개의 테이블을 Join해서 조회 한다면 성능상 분명 악영향을 끼칠 것이다.

  • 가급적 지연 로딩만 사용하자(특히 실무에서)
  • 즉시 로딩을 적용하면 예상치 못한 SQL이 발생한다.
  • 즉시 로딩은 JPQL에서 N+1문제를 일으킨다.
    • N+1이란 최초 쿼리가 1개 나가면 1개의 쿼리 때문에 생기는 N개의 쿼리들이 발생하는 문제다.
    • JPQL을 사용해서 조회를 진행하면 연관된 테이블이 있을 때 그 테이블의 정보까지 모두 조회해서 객체에 들어가게 된다
  • @ManyToOne, @OneToOne은 기본이 즉시 로딩이기 때문에 LAZY로 설정하자
  • @OneToMany, @ManyToMany는 기본이 지연 로딩

지연 로딩 활용

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

지연 로딩 활용 실무

  • 모든 연관관계에 지연 로딩을 사용해라
  • 실무에서는 절대 즉시 로딩을 사용하지 마라.
  • JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라.
  • 즉시 로딩은 상상치 못한 쿼리가 나간다.
출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90

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

JPA - 실전 예제 5 - 연관관계 관리  (0) 2022.06.28
JPA - 영속성 전이(CASCADE)와 고아 객체  (0) 2022.06.28
JPA - 프록시  (0) 2022.06.28
JPA - 실전 예제 4 - 상속관계 매핑  (0) 2022.06.28
JPA - @Mapped Superclass  (0) 2022.06.28
Comments