본문 바로가기
자바/JPA

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

by drCode 2023. 3. 2.
728x90
반응형

어떠한 Member 테이블과 Team 테이블이 있는데

 

Member는 Team에 속하기 때문에 Member는 Team_ID를 가지고 있다.

 

만약 Member 객체를 불러올 때, 그 멤버가 속한 팀의 정보를 다 불러와야할까??

 

방식에 따라 다르겠지만

 

JPA에서는 연관관계 데이터를 불러오는 방법 두 가지 방법을 제공한다.

 

(1) 지연 로딩 (FetchType.LAZY)

 

Member.java

@Entity
public class Member {
	@Id
    @GeneratedValue
    private Long id;
    
    @Column(name = "USERNAME")
    private String name;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    // 이하 생략
}

 

지연 로딩은 영속성 컨텍스트가  Member 를 불러올 때, 연관관계에 있는 Team을 진짜 Team Table 을 조회해서 가져오진 않고 프록시 객체로 가져오는 방법

지연로딩으로 Team 프록시 객체를 가져온다.

 

다대일 설정(@ManyToOne) 에 fetch 전략을  FetchType.LAZY로 하면 지연로딩으로 설정되는데,

 

이렇게 설정한 후 Member 객체를 불러와서 Team 객체를 살펴보면 HibernateProxy 객체임을 알 수 있다.

 

Team 객체를 프록시 객체로 불러온다.

 

실제 Team 객체를 불러올 때 과정

실제로 Team 객체의 필드를 조회해올 때 그 때 Team 테이블에 SELECT 쿼리가 실행된다.

 

Member와 Team을 자주 사용한다면

 

(2) 즉시 로딩 (fetch = FetchType.EAGER)

 

Member.java

@Entity
public class Member {
	
    @Id
    @GeneratedValue
    private Long id;
    
    @Column(name = "USERNAME")
    private String name;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
   // 이하 생략
}

즉시 로딩을 사용하는 것이 좋다.

 

즉시로딩은 Member 객체를 불러올 때 Team 객체를 프록시 객체로 불러오지 않고

 

Member 테이블을 조회 시 Team 테이블을 같이 조회해온다.

 

즉시 로딩은 실제 엔티티를 불러온다
JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회해온다.

조인을 이용하여 함께 조회해온다.

 

그런데 즉시로딩 사용 시 주의사항이 있다.

 

(3) 프록시와 즉시로딩 주의

  • 가급적 지연 로딩만 사용할 것(특히 실무에서)
  • 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생한다.
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다. ( 원하지 않았던 데이터까지 끌고오는 경향)
  • @ManyToOne, @OneToOne은 기본이 즉시로딩 → LAZY로 설정해줘야 함
  • @OneToMany, @ManyToMany는 기본이 지연 로딩이다.

 

지연 로딩 활용 시

Member와 Team은 자주 함께 사용한다면 → 즉시 로딩

Member와 Order는 가끔 사용 → 지연 로딩

Order와 Product는 자주 함께 사용 → 즉시 로딩

지연 로딩 활용
지연 로딩 활용2
지연 로딩 활용3

  • 모든 연관관계에 지연 로딩을 활용하는게 좋다
  • 실무에서 즉시 로딩을 사용하지 않는 편이 좋다
  • JPQL fetch 조인이나, 엔티티 그래프 기능을 사용하라
  • 즉시 로딩은 개발자가 예상하지 못했던 쿼리들이 나갈 수 있다.
728x90
반응형

댓글