inblog logo
|
silver
    프로젝트

    [프로젝트] Lazy Loading으로 인한 LazyInitializationException

    silver's avatar
    silver
    Jan 06, 2025
    [프로젝트] Lazy Loading으로 인한 LazyInitializationException
    Contents
    발생한 에러원인 분석해결 방법 @Transactional(readOnly = true)를 사용하지 않을 경우의 문제점들다른 해결방법🎯 결론

    발생한 에러

    💡
    ERROR 52483 --- [exercise-app-server] [nio-8080-exec-2] c.m.e._.error.GeneralExceptionHandler : Could not initialize proxy [com.metacoding.exerciseappserver.category.Category#1] - no session

    원인 분석

    에러는 Hibernate/JPA의 Lazy Loading 전략과 관련된 에러

    왜 발생했는가?

    1. JPA에서 연관관계 데이터는 기본적으로 Lazy Loading(지연 로딩) 방식으로 동작
    1. 서비스 레이어에서 트랜잭션이 종료된 후, 컨트롤러나 뷰 영역에서 Lazy Loading된 객체에 접근 시도
    1. 세션이 이미 닫힌 상태이므로 프록시 객체를 초기화할 수 없어 예외 발생

    해결 방법

    Service 레이어에 @Transactional(readOnly = true) 적용

    왜 이 방법으로 해결되는가?

    • @Transactional 어노테이션이 메서드 실행 동안 영속성 컨텍스트(세션)를 유지
    • Lazy Loading이 필요한 연관 엔티티에 접근할 때도 세션이 살아있어 정상적으로 데이터 로드 가능

    @Transactional(readOnly = true)를 사용하지 않을 경우의 문제점들

    1. 성능 저하

    • 데이터베이스가 읽기 전용 트랜잭션을 최적화할 수 없음
    • 다중 사용자 환경에서 불필요한 잠금(Lock)으로 인한 성능 저하

    2. 코드 의도 불명확

    • 해당 메서드가 데이터를 수정하지 않는다는 의도를 명확히 표현하지 못함
    • 유지보수 시 다른 개발자의 혼란 유발 가능

    3. 데이터 무결성 위험

    • 실수로 데이터 수정 쿼리가 실행될 가능성
    • 의도하지 않은 데이터 변경으로 인한 무결성 훼손 위험

    4. 예상치 못한 오류

    • 읽기 전용 데이터베이스 환경에서 수정 작업 시도 시 실패
    • 추가적인 예외 처리 필요

    5. 복잡한 트랜잭션 관리

    • 읽기/쓰기 혼합 트랜잭션에서 관리 복잡도 증가
    • 트랜잭션 격리 수준에 따른 일관성 문제 발생 가능

    다른 해결방법

    1. Fetch Join 사용

    @Query("SELECT e FROM Exercise e JOIN FETCH e.category") List<Exercise> findAllWithCategory();
     

    2. @EntityGraph 사용

    @EntityGraph(attributePaths = {"category"}) List<Exercise> findAll();
     

    3. DTO 변환 시점 조정

    @Transactional(readOnly = true) public List<ExerciseDTO> getExerciseList() { List<Exercise> exercises = exerciseRepository.findAll(); // 트랜잭션 내에서 DTO 변환 (Lazy Loading 발생) return exercises.stream() .map(ExerciseDTO::from) .collect(Collectors.toList()); }

    🎯 결론

    읽기 전용 작업에는 반드시 @Transactional(readOnly = true)를 사용하자!
    • 성능 최적화
    • 코드 가독성 향상
    • 데이터 무결성 보장
    • LazyInitializationException 예방
    Share article
    Contents
    발생한 에러원인 분석해결 방법 @Transactional(readOnly = true)를 사용하지 않을 경우의 문제점들다른 해결방법🎯 결론

    silver

    RSS·Powered by Inblog