[JPA] @OneToOne에서 Fetch 전략을 Lazy로 설정했을때 발생하는 이슈
JPA의 유일한 단점은 사용하기 쉬운만큼 성능적인 측면에서 발생할 수 있는 이슈를 간과하기 쉽다는 것인데, 성능이 안나올때 가장 먼저 고려해봐야할 부분이 즉시로딩(EAGER LOADING)으로 설정된 Fetch 전략이 있는지 확인하는 것이다.
하지만 @OneToOne
매핑시 Fetch 전략을 Lazy로 설정해도 EAGER로 동작하는 경우가 있다. 어떤 경우에 이러한 문제점이 발생하는지, 해결책은 무엇인지 예시를 통해 알아보도록 하자
@Entity
public class User {
@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CART_ID")
private Cart cart;
}
@Entity
public class Cart {
@Id
@GeneratedValue
private Long id;
}
해당 예제는 일대일 단방향 매핑으로 외래키를 가지고 있는 USER
가 연관관계의 주인이다.
다음과 같이 USER를 조회해보자.
userRepository.findByEmail(email).orElseThrow();
실행된 쿼리
select
user0_.user_id as user_id2_9_,
user0_1_.created_date as created_3_9_,
user0_1_.modified_date as modified4_9_,
from
user user0_
where
user0_1_.email=?
실행된 쿼리를 보면 Lazy Loadging이 정상적으로 동작한다는 것을 알 수 있다.
@Entity
public class User {
@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CART_ID")
private Cart cart;
}
@Entity
public class Cart {
@Id
@GeneratedValue
@Column("CART_ID")
private Long id;
@OneToOne(mappedBy = "cart", fetch = FetchType.LAZY)
private User user;
}
해당 예제는 User와 Cart가 일대일 양방향 관계를 맺고 있고, 예시1과 동일하게 연관관계의 주인은 외래키를 가지고있는 USER다. 여기서도 아래와 같이 USER를 조회하면 정상적으로 Lazy Loading이 동작한다.
userRepository.findByEmail(email).orElseThrow();
하지만 문제는 Cart를 조회할때 발생한다. 다음과 같이 Cart를 조회해보자.
cartRepository.findById(id).get();