Search
Duplicate

[Java]LazyInitializationException

순서
2
날짜
2023/01/20
사람
상태
Done
오늘은 작업을 하다가 동료가 물어본 예외에대해 작성하려고한다.
배치에서 FetchType.LAZY 를 통해 데이터를 불러오고 있는 상황이었으며, 테스트 코드에서는 잘 작동되고, 쿼츠를 통해서 실행 될 때만 FetchType.LAZY의 객체값을 불러오지 못하는 상황이였다. (LazyInitializationException 발생)
작업을 하면서 오래 걸렸던 이유는 ‘테스트 코드에서는 잘 작동되는데, 왜 쿼츠에서만 잘 안되는 것인가?’ 였다.

FetchType.LAZY

기본적으로 FetchType.LAZY는 프록시 패턴 기반으로 조회 될 때 값을 불러오는 것으로, 이렇게 함으로써 자원을 좀 더 효율 적으로 사용할 수 있다. 사용하지 않는 객체까지 계속 불러오게 된다면, 수많은 메모리만 사용할 것이다.
링크를 참조하면 좀 더 이해하기 쉬움 → [Spring JPA] 프록시
그렇다면 현재 우리의 문제점은 @Transactional이 동작을 안하고, Lazy로딩을 사용해서 영속성 상태의 아닌 값을 불러와 프로시 패턴을 제대로 사용하지 못하고 있다는 것이었다.
이를 체크하기위해 현재 사용하는 위치가 @Controller인지 @Service인지 확인하게 되었고, Quarzts에서 @Componet 에서 @Transcional이 선언되었고, @Service에서 작동시키는게 어떤가 의견을 드려해결하게 되었다.

해결방법들

오늘은 LazyInitializationException에 대해 작성하게되었다.
영속성 상태가 아닌 값을 레이지 로딩으로 불러올때 발생하는 익셉션으로, 같은 문제가 발생된다면
1.
함수에 @Transactional을 선언
2.
즉시 로딩으로 변경 FetchType.Eager
3.
spring 환경 설정 변경 → spring.jpa.open-in-view=true (기본값: false)
a.
하지만 위의 설정은 @Transactional이 종료 되어도 session을 컨트롤러의 응답 시점까지 유지시키는 방법으로, Session의 유지가 길어지기 때문에 권장하지는 않는 방법이다.