순환참조, Lazy 에러

박우영·2023년 5월 8일
0

트러블 슈팅

목록 보기
8/19

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.baeker.baeker.member.Member.myStudies: could not initialize proxy - no Session

라는 에러메시지가 식별되었습니다. 해당 코드를 살펴보면
EventListner


    @EventListener
    public void listen(BaekJoonEvent event) {
        memberService.whenBaekJoonEventType(event.getMember(), event.getSolved());
        studyService.whenBaekJoonEventType(event.getMember(), event.getSolved());
    }

whenBaekJoonEventType(이벤트리스너를 통해 호출되는 메서드)

    @Transactional
    public void whenBaekJoonEventType(Member member, BaekJoonDto dto) {
       
        List<MyStudy> myStudies = member.getMyStudies();
        String today = LocalDate.now().getDayOfWeek().toString().substring(0, 3);

        for (MyStudy myStudy : myStudies) {
            this.saveSnapshot(myStudy.getStudy(), dto, today);

            Study study = myStudy.getStudy().updateBaekJoon(dto);
            studyRepository.save(study);
        }
    }

이와같이 Member 엔티티를 파라미터 로 사용되어있길래 proxy 객체가 호출되어 생긴 오류라고 생각 하였고 아래와 같이 변경했습니다.

EventListener

    @EventListener
    public void listen(BaekJoonEvent event) {
        memberService.whenBaekJoonEventType(event.getMember(), event.getSolved());
        studyService.whenBaekJoonEventType(event.getMember().getId(), event.getSolved());
    }

whenBaekJoonEventType

    @Transactional
    public void whenBaekJoonEventType(Long id, BaekJoonDto dto) {
        Member member = memberservice.getMember(id).get();
        List<MyStudy> myStudies = member.getMyStudies();
        String today = LocalDate.now().getDayOfWeek().toString().substring(0, 3);

        for (MyStudy myStudy : myStudies) {
            this.saveSnapshot(myStudy.getStudy(), dto, today);

            Study study = myStudy.getStudy().updateBaekJoon(dto);
            studyRepository.save(study);
        }
    }

문제가 해결되는줄 알았으나 순환참조 에러메시지

확인해보니 member 1-m mystudy n-1 study 관계로 맵핑되어있고
studyService와 memeberservice 를 서로 참조하기 때문에 생긴 오류였고
이미 파라미터로 넘어오는 id 값이기때문에 Repository에서 바로 넘기기로했다.

whenBaekJoonEventType

    @Transactional
    public void whenBaekJoonEventType(Long id, BaekJoonDto dto) {
        Member member = memberRepository.getMember(id).get();
        List<MyStudy> myStudies = member.getMyStudies();
        String today = LocalDate.now().getDayOfWeek().toString().substring(0, 3);

        for (MyStudy myStudy : myStudies) {
            this.saveSnapshot(myStudy.getStudy(), dto, today);

            Study study = myStudy.getStudy().updateBaekJoon(dto);
            studyRepository.save(study);
        }
    }

0개의 댓글