즉시 로딩과 지연 로딩
2022. 5. 25. 14:07ㆍJava/JPA
프록시 포스팅에 이어서 즉시 로딩과 지연 로딩의 주제로 넘어가 보겠습니다.
지연 로딩 LAZY를 사용해 프록시로 조회
@Entity
public class Member{
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
- member 조회 시 (team을 Join하지 않고) member만 조회 쿼리 나가고
- team 객체는 Proxy 객체로 생성됨.
- 이후실제로 team을 사용하는 시점에 초기화(DB 조회) 되면서 쿼리 나감
만약 Member와 Team을 자주 함께 사용한다면,
즉시 로딩 EAGER를 사용해 함께 조회
@Entity
public class Member {
...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
- 위 Annotation 적용 시, member를 조회할 때 항상 team을 함께 조회함.
- JPA 구현체는 가능하면 조인을 사용해서 SQL 한 번에 함께 조회
❗❗즉시 로딩 주의사항❗❗
1. (가급적) 지연 로딩만 사용 (특히 실무에서)
- Join이 늘어나면 수많은 테이블을 쿼리 할 수도 있음.
2. 즉시 로딩 적용 시 예상치 못한 SQL이 발생
- 💡 JPQL로 “SELECT m from Member m” 쿼리를 전송하면, Join 된 테이블도 중첩되어 조회함.
3.💡 @ManyToOne, @OneToOne은 Default가 EAGER이므로, LAZY로 수정
4. @OneToMany, @ManyToMany는 Default가 LAZY
5. 즉시 로딩은 JPQL에서 N+1문제를 일으킨다
- Member 조회 쿼리를 JPQL로 짰을 때, JPQL은 SQL로 번역되고 Member조회 쿼리 가져옴 (1개)
- 그 후 즉시 로딩 설정한 것이 확인되면, Member의 수(N) 만큼 Join 된 테이블(Team) 조회하는 별도 쿼리 나감(N개)
- 기본적인 해결 방법
- 모든 연관관계를 지연 로딩으로 바꾼 후
- JPQL Fetch 조인
List<Member> members = em.createQuery("select m from Member m join fetch m.team", Member.class)
.getResultList();
지연 로딩 활용
1. “이론적으로는” 아래와 같이 사용하나, 실무에서는 모두 지연 로딩을 권장
2. 실무에서 즉시 로딩을 사용하지 말 것! 즉시 로딩은 상상하지 못한 쿼리가 나간다.
- 필요한 경우 JPQL Fetch 조인이나 Entity 그래프 기능을 사용
JPA기본편 스터디 함께한 Jarry, Matt 항상 감사합니다.
참고 :
https://www.inflearn.com/course/ORM-JPA-Basic
'Java > JPA' 카테고리의 다른 글
[API 개발 고급] 지연 로딩과 조회 성능 최적화(V1) 1/4 (0) | 2022.05.25 |
---|---|
영속성 전이(CASCADE)와 고아 객체 (0) | 2022.05.25 |
프록시(Proxy) (0) | 2022.05.25 |
[API 개발 고급] 조회용 샘플 데이터 입력 (0) | 2022.05.24 |
[API 개발] 회원 등록, 수정, 조회 API (0) | 2022.05.24 |