<TIL> 71. [JPA] 즉시로딩/지연로딩(FetchType.LAZY or EAGER)

YUJIN LEE·2023년 3월 22일
0

개발log

목록 보기
66/149

비즈니스 로직에서 연관관계가 걸려있을 때, 함께 조회하지 않게 하는 방법은
JPA의 지연로딩 LAZY를 사용해 프록시로 조회하는 방법으로 해결가능.

Entity 사이의 관계가 다대일 @ManyToOne 관계로 매핑되어있는 상황에서,
@ManyToOne 어노테이션에 fetch 타입을 줄 수 있다.

@ManyToOne(fetch = FetchType.LAZY)

지연로딩(LAZY)

엔티티 조회 시점이 아닌 엔티티 내 연관관계를 참조할 때 해당 연관관계에 대한 SQL이 질의되는 기능,
fetch = FetchType.LAZY 옵션으로 지정할 수 있다.

엔티티 조회 시, 연관관계 필드는 프록시 객체로 제공.

즉시로딩

엔티티 조회 시 연관관계에 있는 데이터까지 한번에 조회해오는 기능,
fetch = FetchType.EAGER 옵션으로 지정할 수 있다.

즉시로딩으로 조회된 엔티티의 연관관계 필드에는 실제 엔티티 객체가 반환.

주의사항

  • 실무에서는 가급적 지연로딩 사용
  • 즉시로딩 사용시 예상하지 못한 SQL 발생할 수 있음.
  • 즉시로딩은 JPQL에서 N+1 문제를 일으킨다.
    - 실무에서 복잡한 쿼리를 많이 풀어내기 위해 JPQL 많이 사용.
    • em.find()는 PK를 정해놓고 DB에서 가져와 JPA 내부에서 최적화 할 수 있다.(한방쿼리)
    • 하지만, JPQL에선 입력 받은 query string이 그대로 SQL로 변환된다.
    • N+1의 문제의 의미는 쿼리를 1개 날렸는데, 그것 때문에 추가 쿼리가 N개 나간다는 의미.
      • 실무에서 엔티티 중 함께 사용하는 경우 LAZY로 해놓고 계속 쿼리 두번 날려서 조회를 해야할까?
        -> 이런 경우 JPQL의 fetch join을 통해 해당 시점에 한방 쿼리로 가져와 사용가능.
        -> 추가로, 엔티티그래프와 어노테이션으로 푸는 방법, 배치 사이즈 설정으로 해결가능.
        -> 대부분 fetch join으로 해결

연관관계 별 fetch 옵션 기본값

  • @ManyToOne : EAGER
  • @OneToOne : EAGER
  • @ManyToMany : LAZY
  • @OneToMany : LAZY
profile
인정받는 개발자가 되고싶습니다.

0개의 댓글