테스트 코드를 짜던 도중 Lazyloading Exception
을 만났다.
이 부분에서 findMember의 recruit를 호출하는데, 영속성 컨텍스트 밖에서 호출했기 때문이다.
먼저 문제의 원인은
영속성 컨텍스트 밖에서 프록시 객체를 초기화하려고 했기 때문에 발생한 에러
이다.
findById로 조회한 findMember는 영속 상태가 맞지만, 프록시 객체로 생성된 recruit 객체를 지연 로딩으로 초기화 시도를 했고, 이는 영속성 컨텍스트 바깥에서 이루어졌기 때문이다. (OSIV = false : 영속성 컨텍스트 범위 = 트랜잭션 범위)
테스트 메서드/클래스 레벨에 @Transactional 붙이기
물론 이렇게 해도 해결되지만, 이는 근본적인 해결책이 될 수 없다.
현재 나는 컨테이너를 띄워서 실제 서비스와 같은 환경에서의 테스트를 시도하고 있는데, @Transactional을 사용해 테스트에서 강제로 트랜잭션을 유지하도록 하면 애플리케이션 실행 환경에서의 트랜잭션 동작 여부는 테스트 사항에서 빠지게 된다.
즉, service layer에 @Transactional을 붙이지 않아도 테스트에서는 통과가 되어버리는 것이다.
fetch type을 EAGER로 설정
이것도 올바른 해결방법이 아니다. 지연 로딩을 의도했는데, 테스트를 통과하려고 fetch type을 수정하는 건 옳지 않다.
repository에 fetch join을 쿼리 추가
위의 쿼리를 이용해 테스트를 시도하면 테스트에 성공한다.
하지만 실제 애플리케이션 환경에서 fetch join을 사용하는 상황이라면 이렇게 사용해도 되겠지만, fetch join이 필요하지 않은 경우라면 이것도 제대로된 방법은 아니라고 느껴지긴 한다. 일단 임의로 테스트용 쿼리를 만들어놓고, 더 좋은 방법을 생각해봐야 할 것 같다.