일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Kotlin
- DB
- ocp
- 정규화
- 스레드 풀
- AWS
- Kafka
- java
- 갱신 이상
- JPA
- buildSrc
- 삽입 이상
- 데이터베이스
- 낙관적 락
- 비관적 락
- 삭제 이상
- gatway
- 자료구조
- MSA
- 자바
- Spring
- Redis
- 캐시 오염
- null
- Dirty Checking
- 3-way handshaking
- 페이지네이션
- HTTP
- well-know port
- 네트워크
- Today
- Total
어 나 갱수.
[JPA] 즉시로딩과 지연로딩 🐥 본문
오늘은 즉시 로딩과 지연 로딩에 대해 정리해 보겠습니다. 각각 어떤 상황에서 사용해야 하고 왜 사용해야 하는지 알아보겠습니다.
JPA는 데이터를 조회할 때, FetchType으로 즉시로딩(Eager)과 지연로딩(Lazy)가 있습니다.
Fetch Type이란 ?
Fetch Type이란, JPA에서 하나의 Entity를 조회할 때, 연관관계에 있는 객체들을 어떻게 가져올 것이냐를 나타내는 설정값입니다.
- JPA는 ORM기술로, 사용자가 직접 쿼리문으로 쿼리를 생성하지 않고, JPA에서 JPQL을 이용해서 쿼리를 생성해 줍니다.
- JPA에서 Entity의 필드와 객체를 보고 쿼리문을 생성합니다.
- 따라서 Entity에 연관관계 매핑이 되어있으면 그 Entity들까지 함께 조회하게 되는데, 그 매핑되어 있는 Entity를 어떻게 가져올 것인가에 대한 설정입니다.
각 연관관계의 default 속성은 다음과 같습니다.
~One으로 끝나는 연관관계는 EAGER속성이 defalut이고 ~Many로 끝나는 연관관계는 LAZY속성이 default입니다.
- @ManyToOne : EAGER
- @OneToOne : EAGER
- @ManyToMany : LAZY
- @OneToMany : Lazy
즉시로딩 (Eager)
즉시로딩이란 Entity를 조회할 때 매핑되어있는 다른 Entity들을 한 번에 불러오는 것을 말합니다.
아래에는 Member 엔티티와 Team엔티티가 N:1 매핑으로 관계를 맺고 있습니다.
Member 엔티티에서 FetchType을 EAGER로 설정하였습니다.
@Entity
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
JPQL로 Member를 조회해 보겠습니다.
Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();
위와 같이 JPQL로 member를 조회하는 쿼리문을 작성하면
// 멤버를 조회하는 쿼리
select
member0_.id as id1_0,
member0_.team_id as team_id3_0_,
member0_.username as username2_.0_
from
Member member0_
// 팀을 조회하는 쿼리
select
team0_.id as id1_3_0_,
team0_.name as name2_3_0
from
Team team0_
where
team0_.id=?
다음과 같이 FetchType을 EAGER로 설정하면 Member를 조회할 때 Team 엔티티도 함께 조회해서 쿼리가 같이 발생하는 것을 볼 수 있습니다.
지연로딩 (Lazy)
지연로딩이란, 필요한 시점에 연관된 객체의 데이터를 불러오는 것을 말합니다.
위의 예제에서 Fetch Type만 바꿔서 실행해 보겠습니다.
@ManyToONe(fetch = FetchType.Lazy)
JPQL을 사용해서 똑같이 Member 객체를 조회해 보겠습니다.
Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();
// Team을 조회하는 쿼리는 발생하지 않음!
select
member0_.id as id1_0,
member0_.team_id as team_id3_0_,
member0_.username as username2_.0_
from
Member member0_
위에 쿼리문을 보면 Team을 조회하는 쿼리문은 발생하지 않았습니다.
정리
정리하면 즉시로딩은 연관된 데이터를 모두 가져온다는 장점이 있지만, 실무에서 엔티티 간의 관계가 복잡해질수록 조인으로 인한 성능 저하를 피할 수 없고 JPQL에서 발생하는 N+1을 일으킵니다.
즉시로딩은 불필요한 조인까지 포함해 처리하는 경우가 많아서 가급적 `지연 로딩`을 권장합니다.
'JPA' 카테고리의 다른 글
[JPA] 더티 체킹 (Dirty Checking) (0) | 2024.08.09 |
---|---|
[JPA] JPA와 Hibernate에 대해 알아보자 😏 (0) | 2024.03.17 |
[JPA] 페이징 처리, JPA Pagination 이란 🦫 (1) | 2024.02.25 |