fetch join은 Spring Boot + JPA (Hibernate) 환경에서 지연 로딩(LAZY) 관계의 데이터를 한 번의 쿼리로 함께 조회할 때 사용하는 방법
JPA에는 엔티티에 관계를 맵핑할 때 지연 로딩과 즉시 로딩 설정할 수 있다.
일반 Join : 연관 Entity에 Join을 걸어도 실제 쿼리에서 SELECT 하는 Entity는 오직 JPQL에서 조회하는 주체가 되는 Entity만 조회하여 영속화한다.
Fetch Join : 조회의 주체가 되는 Entity 이외에 Fetch Join이 걸린 연관 Entity도 함께 SELECT 하여 모두 영속화
Member Entity와 Team Entity가 @ManyToOne 일 때 Entity 클래스에 서로의 관계를 표시해 준다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString
public class Member {
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;
private String username;
private int age;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
@ToString.Exclude
private Team team;
}
Fetch Join 을 사용해야 하는 상황
1. @ManyToOne, @OneToOne 연관 관계의 객체가 반복적으로 로딩될 때
@Query("SELECT m FROM Member m JOIN FETCH m.team")
List<Member> findAll(); // N+1 문제 해결
2. JPQL 또는 QueryDSL로 다대일 관계를 한 번에 조회하고자 할 때
@ManyToOne, @OneToOne 관계는 fetch join으로 쉽게 한 쿼리에 묶을 수 있음
Fetch Join을 사용하면 안 되는 경우
1. 컬렉션(@OneToMany, @ManyToMany)에 페치 조인을 사용하면서 페이징이 필요한 경우
JPA는 fetch join이 있는 경우 Pageable 정보를 무시하거나, 메모리에서 잘라내기 때문에 성능 이슈 발생
@BatchSize 또는 별도 쿼리
2. 복수 개의 컬렉션을 동시에 Fetch Join 할 때
@Query("SELECT d FROM Department d JOIN FETCH d.employees JOIN FETCH d.projects")
여러 컬렉션이 곱해져서 결과가 기하급수적으로 커질 수 있음
해결 방법: 컬렉션 하나만 fetch join, 나머지는 batch fetch 사용
'Spring Boot > Basic' 카테고리의 다른 글
Spring Boot Entity 변수 일괄 변경 방법 (0) | 2025.05.30 |
---|---|
Spring Boot 이미지 로딩 문제 (0) | 2025.05.24 |
Spring Boot 3.4.5 QueryDSL 예제 ProductSearch (0) | 2025.05.11 |
Spring Boot 3.4.5 QueryDSL 예제 개선 (0) | 2025.05.04 |
Spring Boot 3.4.5 QueryDSL 예제 (0) | 2025.05.04 |