본문 바로가기
웹개발/JPA

즉시 로딩과 지연 로딩

by 철없는민물장어 2023. 7. 16.
728x90
반응형

Member와 Team이 연관관계로 묶여있다고 할 때,

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

 

프록시 개념 필요

2023.07.14 - [JPA] - 프록시

지연 로딩
@Entity
public class Member {
...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="TEAM_ID")
    private Team team;
  ...
  }

FetchType.LAZY로 설정하면 프록시로 조회하게 된다.

 

예를들어 멤버1을 조회하면, 멤버1객체를 가져오고, 멤버1과 관련된 team은 프록시로 가져온다.

이후, team의 속성을 사용하는 시점에 프록시 객체가 초기화되면서 쿼리가 발생하고 team객체를 가져오게 된다.

 

Member와 Team이 가끔씩만 함께 사용되는 경우에는 지연로딩이 효율적일 수 있다.


즉시 로딩
@Entity
public class Member {
...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="TEAM_ID")
    private Team team;
  ...
  }

FetchType.EAGER로 설정한다.

 

이 경우 Member객체를 조회하면 member객체와 team객체를 조회하는 쿼리가 동시에 발생하고,

member엔티티와 team엔티티를 즉시 가져온다.(프록시를 사용하지 않음)


실무에서는 가급적 지연 로딩을 사용한다.(가급적이 아니라 그냥 다 지연로딩 쓰라고 하심)

1. 즉시로딩을 적용하면 예상하지 못한 SQL이 나갈 수 있다.

(연관관계가 많으면 수많은 조인이..)

2. JPQL에서 N+1문제를 발생

em.createQuery("select m from Member m",Member.class);

이 JPQL을 실행시키면 N개의 Member객체를 가져온다.(쿼리1번 발생. select * from Member )

이후, N개의 Member객체 각각에 관련된 Team객체를 가져오는 쿼리가 N번 발생한다.

("select * from Team where TEAM_ID = xxx"가 최대 N번 발생)

 

(JPQL을 잘 활용하면 이 문제를 해결할 수 있긴 하다. JPQL은 추후에..)

 

@XToOne은 즉시로딩(EAGER)이 기본설정으로 되어있으니 LAZY로 설정해주는것이 필요할것이다.

 

728x90
반응형

'웹개발 > JPA' 카테고리의 다른 글

값 타입  (0) 2023.07.19
영속성 전이 CASCADE  (0) 2023.07.19
프록시  (0) 2023.07.14
@MappedSuperclass  (0) 2023.07.07
상속관계 매핑  (0) 2023.07.07

댓글