본문 바로가기
Spring

[Spring/JPA] N+1과 @OneToOne LEFT JOIN

by noddu 2026. 1. 5.
728x90
반응형
N+1문제 해결
@Entity(name = "Users")
public class User {
    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"))
    @Enumerated(EnumType.STRING)
    @Column(name = "role")
    private Set<Role> roles = new HashSet<>();
}

@ElementCollection(fetch = FetchType.EAGER) 사용으로 권한을 가져올 때 편하지만

N+1 발생: 유저 10명을 조회하면 각 유저 쿼리 1번 + 각 유저의 권한을 가져오는 쿼리 10번이 실행

 

해결책: Batch Size: default_batch_fetch_size: 100 설정을 통해 10번의 쿼리를 단 1번의 IN절 쿼리로 합친다

(권한은 회원을 조회할 때 계속 필요할 것 같아 EAGER로 놔두기로, 1+1 쿼리 실행)

 

반응형

 

LEFT JOIN 실행
Survey TripRecommendation
주인X(FK 없음) 주인(FK 있음)

 

난 시킨 적 없는데 왜 LEFT JOIN이 나갈까? 양방향 1:1(@OneToOne) 관계에서 발생

 

Survey 테이블에는 상대방(TripRecommendation)이 있는지 알 수 있는 컬럼이 없다

JPA는 Survey 객체를 만들 때 recommendation 필드에 null을 넣을지, 객체를 넣을지 결정해야 하는데

결국 상대방 테이블을 뒤져봐야만 알 수 있기 때문에 JPA는 안전하게 LEFT JOIN을 던져 한꺼번에 확인한다

 

 

728x90

 

참고: 연관관계별 JOIN 동작 요약
관계 FK 위치 기본 로딩 조인 특징
@ManyToOne 나(Survey) LAZY(권장) 내가 FK를 가졌으므로 조인 없이도 내 상태 확인 가능
@OneToMany 상대방 LAZY 컬렉션이라 어차피 나중에 따로 가져옴 (조인 안 함)
@OneToOne (주인X) 상대방 EAGER/LAZY Null 여부 확인을 위해 강제로 조인 발생

 

 

 

반응형