[Spring JPA] 즉시로딩과 지연로딩

2021. 6. 28. 18:51Spring/JPA

즉시로딩과 지연로딩

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

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

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

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)//이 부분이 LAZY
    @JoinColumn(name = "TEAM_ID")
    private Team team;

지연로딩


2021-06-28-4-08-16.png

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


2021-06-28-4-09-27.png

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

2021-06-28-4-09-32.png

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

실제 코드

Team team = new Team();
            team.setName("teamA");
            em.persist(team);

            Member member1 = new Member();
            member1.setUsername("hello");
            member1.setTeam(team);

            em.persist(member1);

            em.flush();
            em.clear();
            Member m = em.find(Member.class, member1.getId());
            System.out.println("m.getTeam().getClass() = " + m.getTeam().getClass()); //                                                                                                                                                    프록시로 가져온다.

            System.out.println("==============");
            m.getTeam().getName(); // 실제 team을 사용하는 시점에 프록시를 초기화하고 실제 값을 가져온                                                                            다.
            System.out.println("==============");

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

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

즉시로딩


2021-06-28-4-53-43.png

  • 즉시로딩(EAGER)는 Member 조회시 항상 Team도 조회
  • JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회

프록시와 즉시로딩 주의!!!


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

2021-06-28-5-25-06.png

지연 로딩 활용 - 실무


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

참고자료

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

Java8 Stream 특정 Key 중복제거  (0) 2022.05.30
JPQL은 만능이 아니다!  (0) 2021.12.23
Spring JPA [상속관계 맵핑]  (0) 2021.06.17
[Spring JPA] 다양한 연관관계 매핑  (0) 2021.04.19
Spring JPA 영속성 컨텍스트  (0) 2021.02.28