자바칩
[JPA] 즉시 로딩(FetchType.EAGER)과 지연 로딩(FetchType.LAZY) 본문
728x90
JPA(Java Persistence API)에서 엔티티를 로드하는 방식은 크게 두 가지로 나뉜다.
- 즉시 로딩(FetchType.EAGER)
- 지연 로딩(FetchType.LAZY)
각각의 로딩 방식은 엔티티를 데이터베이스에서 가져오는 시점과 방식에 차이가 있다.
즉시 로딩 (FetchType.EAGER)
즉시 로딩은 엔티티가 로드될 때 관련된 엔티티들도 함께 로드되는 방식이다.
즉, 주 엔티티를 가져오는 시점에 관련된 모든 엔티티들을 즉시 데이터베이스에서 조회한다.
특징
- 주 엔티티와 연관된 모든 엔티티들을 한 번에 로드하기 때문에 N + 1 문제를 유발할 수 있따.
- 쿼리가 복잡해질 수 있으며, 성능에 영향을 줄 수 있다.
- 코드가 단순해지고, 관련 엔티티에 바로 접근할 수 있어 편리하다.
- @ManyToOne과 @OneToOne (@XXXOne) 의 기본 값이다.
사용 예시
@Entity
public class Member {
@ManyToOne(fetch = FetchType.EAGER)
private Team team;
}
지연 로딩 (FetchType.LAZY)
지연 로딩은 주 엔티티가 로드될 때 관련된 엔티티는 로드되지 않고, 실제로 접근할 때 로드되는 방식이다.
즉, 연관된 엔티티에 처음 접근하는 시점에서 데이터베이스 조회가 발생한다.
특징
- 필요한 시점에만 데이터를 조회하기 때문에 초기 로딩 시 성능이 개선된다.
- 프록시 객체를 사용하여 실제 데이터베이스 조회를 지연시킨다.
- N + 1 문제를 피할 수 있으며, 쿼리가 단순해진다.
- @OneToMany와 @ManyToMany (@XXXMany) 의 기본 값이다.
사용 예시
@Entity
public class Member {
@ManyToOne(fetch = FetchType.LAZY)
private Team team;
}
예제 코드
Member와 Team 엔티티 간의 관계를 예시로 들어 즉시 로딩과 지연 로딩을 비교하겠다.
@Getter
@Setter
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY) // 또는 FetchType.EAGER
private Team team;
}
@Getter
@Setter
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
}
즉시 로딩
Member member = entityManager.find(Member.class, 1L);
Team team = member.getTeam(); // 이 시점에서 Team도 함께 로드된다.
지연 로딩
Member member = entityManager.find(Member.class, 1L);
Team team = member.getTeam(); // 이 시점에서 Team이 로드된다. (프록시 객체가 초기화됨)
장단점 비교
- 즉시 로딩
- 장점: 단순한 코드, 편리한 접근
- 단점: 초기 로딩 시 성능 저하, N + 1 문제 발생 가능
- 지연 로딩
- 장점: 초기 로딩 성능 향상, 필요한 시점에만 데이터 조회
- 단점: 프록시 객체 처리 필요, 코드가 다소 복잡해질 수 있음
결론
적절한 로딩 방식을 선택하는 것은 애플리케이션의 성능과 유지 보수성에 큰 영향을 미친다. 따라서 엔티티 간의 관계와 사용 패턴을 고려하여 최적의 로딩 방식을 선택하는 것이 중요하다. 기본적으로는 지연 로딩(FetchType.LAZY)을 사용하는 것이 성능 면에서 유리하며, 즉시 로딩이 필요한 경우에만 FetchType.EAGER를 사용하는 것이 좋다.
그 전까지는 아무 생각 없이 @ManyToOne과 @OneToOne을 쓰면서 아무런 값도 세팅하지 않고 프로젝트를 개발함으로써 성능 저하가 발생했던 것 같다. 이제부터는 상황에 따라 즉시 로딩과 지연 로딩을 잘 선택해서 성능 향상이 되도록 개발해야겠다.
'Study > JPA' 카테고리의 다른 글
[JPA] Response를 DTO로 해야 하는 이유, N + 1 문제 해결 방법, 양방향 매핑 순환 참조 (1) | 2024.08.04 |
---|---|
[JPA] @OneToMany (0) | 2024.08.04 |