@OneToOne 지연로딩?
@OneToOne 양방향 연관관계에서 조회 시 Lazy로딩이 먹히지 않았다.
좀더 정확히는 연관관계의 주인이 아닌 쪽에서 엔티티 조회하니 Lazy로딩이 먹히지 않았다!!
이유와 해결책을 정리해두려 한다.
양방향 연관관계 엔티티
도서와 도서이미 1대1 관계
public class BookEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long bookCode;
...
@OneToOne(fetch = FetchType.LAZY, mappedBy = "book",cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
private BookImageEntity bookImage;
}
public class BookImageEntity{ //연관관계의 주인
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "img_no")
private Long imgNo;
...
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="book_no")
private BookEntity book;
}
case1) 연관관계의 주인이 아닌 엔티티에서 조회
연관관계의 주인이 아닌 엔티티에서 FetchType.LAZY 걸려있음에도 지연로딩은 먹히지 않았다.
case2) 연관관계의 주인인 엔티티에서 조회
연관관계의 주인에서 하니 정상적으로 지연로딩이 작동하였다.
정리하면,
@OneToOne 양방향 연관관계에선 연관관계의 주인인 엔티티에서만 조회 시, Lazy 동작한다.
왜 그럴까??
Lazy 로딩할 연관된 엔티티엔 프록시가 들어가야 하며, 프록시는 null을 프록시객체로 감쌀 수 없다
그렇기에 null을 할당할지, 프록시객체를 할당할지 결정해야 한다.
연관관계의 주인은 FK 컬럼을 가지고 있기에 FK컬람 값 유무로 연관된 엔티티에 대한 존재 유무를 판단할 수 있다.
FK가 존재하면 아 연관된 데이터 있다 프록시객체 할당!
FK 존재하지 않으면 연관된 데이터 없다 null 할당!
그러나 연관관계의 주인이 아닌 쪽에선 FK를 가지고 있지 않기 때문에 연관관계를 맺는 엔티티의 존재유무를 판단할 수 없다. 따라서, 필수적으로 쿼리를 돌려 null로 할당할지 프록시객체를 할당할지 정하게 되므로 Lazy로딩이 무시되어 Eager로 동작하게 된다.
@OneToMany는 문제 없나?
연관관계의 주인은 다쪽에 있다. 일쪽에선 다의 존재 유무를 알 수 없다.
그러나 일에선 다의 엔티티를 collection으로 지니고 있다. (ex. List<BookImageEntity> bookImageList)
컬렉션의 경우는 null의 표현을 해당 컬렉션이 비어있다 라고 정의할 수 있기에 연관관계의 주인이 아닌 곳에서도 Lazy로딩이 가능하다.
@ManyToOne은 문제 없을까?
다쪽에서 외래키를 지니고 있기에 연관된 엔티티에 대한 존재유무를 판단할 수 있다.
문제 없다
해결책?
연관관계의 주인이 아닌 쪽에서의 조회 시 Lazy로딩 해결책으론 아래 두 가지를 생각하였다.
1. 연관관계의 주인 변경
2. fetchJoin -> 해당 방법으로 해결
추가로 아래 방법도 있다고 한다.
3. OneToOne을 OneToMany나 ManyToOne으로 분리
참고)
https://jeong-pro.tistory.com/249
JPA @OneToOne은 FetchType.LAZY가 안 먹힐 수 있다?
JPA에서 @OneToOne 연관관계일 때 지연 로딩이 안 될 수 있다? 이제는 JPA가 상당히 많이 쓰이고 있기도 하고 유명한 모 강의도 있어서 많은 사람들이 잘 알고 쓰고 있긴하다. 그러나 실제 경험해본
jeong-pro.tistory.com
https://hwannny.tistory.com/116
OneToOne 연관관계에서 Lazy 로딩 전략이 작동하지 않는 이슈
들어가며 연관관계 주인이 아닌 엔티티쪽에 OneToOne 연관관계 및 Lazy 로딩 전략을 설정한 뒤 연관관계 주인이 아닌 엔티티 조회시 당연하게 Lazy 로딩될줄 알았지만 쿼리로그를 확인해보니 Eager 로
hwannny.tistory.com
https://shirohoo.github.io/spring/spring-data-jpa/2021-05-31-one-to-one/
OneToOne에 대해서
JPA 사용 시 만악의 근원, @OneToOne에 대한 고찰
shirohoo.github.io