[Error] unable to evaluate the expression method threw 'org.hibernate.LazyInitializationException'

Astin·2024년 1월 29일
0

📢 오류 발생

로그인을 시도할 때 성공하면 jwt토큰을 만들어서 반환하는 로직을 만들었는데
위와 같은 에러 발생

Users

@OneToMany(mappedBy ="user")
prive List<UserRole> userRoles = new ArrayList<>();

JwtAuthenticationFilter

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication authentication) throws IOException, ServletException {
		...

        List<String> roles = user.getUser().getUserRoles().stream()
                .map((role) -> role.getRole().getRole())
                .collect(Collectors.toList());

		...
    }

🔔 원인 파악

join 테이블의 경우 기본적으로 lazy loading을 사용하는데 filter에서 동작할 당시 엔티티의 상태는 영속성 컨텍스트에 저장되었다가 분리된 상태 즉, 준영속 상태이므로 지연로딩을 사용하지 못한다.

💯 배경지식1 : 컨트롤러나 뷰 같은 프리젠테이션 계층에서 엔티티는 준영속 상태가 된다.

  • 즉, service/repository 계층까지 가지 못한 filter 단계에서 조회하려는 엔티티는 준영속 상태인 것

💯 배경지식2 : lazy loading은 영속 상태에서만 사용할 수 있다.

✅ 원인 해결

Lazy 에서 Eager로 전환
이렇게 되면 영속 상태와 관계없이 join 테이블을 만들어서 조회가 가능해진다.

Users

@OneToMany(mappedBy ="user", fetch = FetchType.EAGER)
prive List<UserRole> userRoles = new ArrayList<>();

🤔 개선방안

다만 이 경우 User를 조회해올 때마다, 항상 userRoles의 조회가 같이 이루어지므로 불필요한 정보를 항상 조회해오게 되는 것은 아닌지 충분히 고려할 필요가 있다.

따라서 다음시간에는 다른 방식의 개선방안에 대해 살펴볼 예정이다.

+ 추가) 준영속 상태의 지연로딩을 해결하는 법

https://velog.io/@blacknwhites/%EC%A4%80%EC%98%81%EC%86%8D-%EC%83%81%ED%83%9C%EC%9D%98-%EC%A7%80%EC%97%B0%EB%A1%9C%EB%94%A9%EC%9D%84-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B2%95

참고자료

https://dmaolon00.tistory.com/entry/Error-unable-to-evaluate-the-expression-method-threw-orghibernatelazyinitia

https://velog.io/@lsj8367/%EC%A4%80%EC%98%81%EC%86%8D-%EC%83%81%ED%83%9C%EC%9D%98-%EC%A7%80%EC%97%B0%EB%A1%9C%EB%94%A9%EC%9D%84-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

0개의 댓글

관련 채용 정보