org.hibernate.LazyInitializationException 에러 #172
janeljs
started this conversation in
Troubleshooting docs
Replies: 2 comments 1 reply
-
|
혹시 세 번째 방법 설명 부탁드려도 될까요?? |
Beta Was this translation helpful? Give feedback.
1 reply
-
적용 가능한지 확인 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
문제
위의 코드에서
group.addSchedule(schedule);를 실행하는데 org.hibernate.LazyInitializationException이 발생했습니다.해당 에러는 영속성 컨텍스트가 종료되어 버려 지연 로딩을 할 수 없을 때 발생한다고 합니다.
즉, 프록시 객체를 통해 데이터베이스에서 lazy-loading된 객체를 가져오려고 하지만 하이버네이트 세션은 이미 종료되어 발생하는 에러입니다.
(보통 트랜잭션 밖에서 엔티티를 조회할 때 발생)
Session
Lazy Loading
Proxy Object
해결
@Transactional어노테이션을 붙여 해결했습니다.2차 문제 발생
테스트에
@Transactional어노테이션을 붙이니 내부에서 API를 호출할 때 새로운 트랜잭션이 시작되어 한 테스트에 두 가지의 트랜잭션이 존재하는 문제가 발생했습니다.내용 추가
@Transactional어노테이션은 같은 쓰레드에서만 동작한다. 그러나 restassured를 이용하여 테스트를 진행할 시 다른 쓰레드에서 동작한다.→ JUnit 테스트가 embedded servlet container와 다른 쓰레드에서 실행되기 때문에 발생하는 문제이다.
→ 2개의 트랜잭션과 데이터베이스 커넥션이 열린다.
+) 스프링 컨테이너는 스레드마다 다른 트랜잭션을 할당하며, 트랜잭션이 다를 경우 다른 영속성 컨텍스트에 접근한다.
해결
테스트에서 해당 어노테이션을 제거하고 데이터 초기화를 담당하는 TestDataSetup 클래스를 정의하였습니다.
→ 다른 테스트에서도 자주 쓰일 것 같아 TestEntityManager 클래스로 분리
3차 문제 발생
테스트 내부에서 RestAssured로 호출하는 메서드가 Lazy 로딩되는 컬렉션을 저장하려고 하면 트랜잭션이 유지되어야 하는데, 테스트 메서드에
@Transactional어노테이션을 붙이면#2차 문제가 발생합니다.해결 1
MultipleBagFetchException을 막기 위해 하이버네이트에서 제공하는@Fetch(value = FetchMode.SUBSELECT)를 사용하였지만, 다른 구현체를 사용할 경우 작동하지 않습니다.해결 2
TestEntityManager에 findAndConsume() 메서드를 추가하여 임시로 해결
해결 3
Filter를 이용해서 JUnit 테스트에서 열린 트랜잭션을 서블릿 컨테이너까지 전파하는 방법으로 해결할 수 있을 것 같습니다.
Beta Was this translation helpful? Give feedback.
All reactions