728x90
반응형
개발 중에 이러한 warning을 발견했다.
... M_OP_LINK] entity uses both @NotFound(action = NotFoundAction.IGNORE) and FetchType.LAZY. The NotFoundAction.IGNORE @ManyToOne and @OneToOne associations are always fetched eagerly.
FetchType.LAZY로 써줬는데, EAGER로 동작하더라
warning을 해석해보면 ~One으로 끝나는 join 은 NotFoundAction.IGNORE와 FetchType.LAZY를 함께쓰면 언제나 FetchType.EAGER로 동작한다는 것을 알 수 있다.
왜 그럴까?
먼저 LAZY가 어떻게 동작하는지 보자.
예를 들어서 User와 Cart를 join한다고 해보자.
- 지연 로딩은 로딩되는 시점에 Fetch 전략이 Lazy로 설정되어있는 엔티티를 프록시 객체로 가져온다. 해당 예제에서는 User를 조회할때 cart를 프록시 객체로 가져오게 된다.
- 이후 실제로 Cart 객체를 사용하는 시점에 초기화 되면서 쿼리가 실행된다.
- 예를들어, getCart() 처럼 cart 객체가 사용되었을때 쿼리가 실행되는 것이다.
이렇게 지연 로딩으로 설정이 되어있는 엔티티를 조회할 때는 프록시로 감싸서 동작하게 되는데, 프록시는 null을 감쌀 수 없기 때문에 이와 같은 문제점이 발생하게 된다. 즉, 프록시의 한계로 인해 발생하는 문제이다.
CART라는 테이블에는 USER를 참조할 수 있는 컬럼이 존재하지 않는다. USER가 null이 아니라고 해도, CART의 입장에서는 USER가 null인지 null이 아닌지 확인할 방법이 없다.
따라서 USER의 존재 여부를 확인하는 쿼리를 실행하기 때문에 지연 로딩으로 동작하지 않는 것이다.
해결방법
완벽히 해결할 방법은 존재하지 않는다고 한다.
구조를 변경해야 해소할 수 있다.
- 양방향 매핑이 반드시 필요한지, FK가 있는 주테이블에서 연관관계를 맺을 수 있다면 그렇게 하는 것이 좋다.
또는 @BatchSize를 이용해 한번에 실행되도록 한다.
참고
https://1-7171771.tistory.com/143
728x90
반응형
'jpa' 카테고리의 다른 글
[JPA] QueryDSL JPA 사용하기 (0) | 2023.08.09 |
---|---|
[jpa] Spring Data Jpa는 왜 interface만 생성해줘도 작동할까? + Spring Data Jpa 확장하기 (0) | 2023.08.08 |
[jpa] 지연로딩과 즉시로딩 FetchType.EAGER, LAZY, 프록시 (0) | 2023.03.31 |
[jap] jpa entity 변수명 대소문자 바뀜 (3) | 2023.03.15 |
[jpa] 양방향 매핑 깊게 알아보기, JOIN(@OneToMany, @ManyToOne), where조건으로 select하기 (2) | 2023.03.14 |