[Spring Data JPA] LazyInitializationException (작성중)

갓김치·2021년 6월 29일
0

예외

목록 보기
14/28
post-custom-banner

상황

컨트롤러에서 매개변수를 정리하고 서비스로 넘기고싶은데, 엔티티에 접근하려니 예외 발생...

  • 컨트롤러 소스
        // 1. get question id list from request
        List<Integer> questionIdList = responseSaveDTO.getQuestionOptionSaveDTOList().stream()
                                                                                .map(QuestionOptionSaveDTO::getQuestionId)
                                                                                .collect(Collectors.toList());

        // 2. find question option list with matching question id
        // if question id is not valid, the result won't contain any options to that id.
        List<QuestionOptionEntity> questionOptionEntityList = questionOptionService.findByQuestionIdIn(questionIdList);

        // 3. set up valid response
        List<QuestionOptionSaveDTO> validOptionList = responseSaveDTO.getQuestionOptionSaveDTOList().stream()
                                                                .filter(response -> questionOptionEntityList.stream()
                                                                .allMatch(qoe -> qoe.getQuestionEntity().getId() == response.getQuestionId() && qoe.getDegree() == response.getDegree()))
                                                                .collect(Collectors.toList());
  • 3번단계에서 QuestionEntity에 전혀 접근을 못하고 있다

이유

  • QuestionOptionEntity에서 QuestionEntity를 아래와 같이 가지고있음
public class QuestionOptionEntity extends BaseTimeEntity{
	..생략
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="question_id") // fk
    private QuestionEntity questionEntity;
}
  • 지연로딩만 생각하고 서비스에 @Transactional을 붙여주었음 -> 해결 방법이 아니다
    • 왜냐하면, 이미 transaction context를 벗어난 컨트롤러에서 entity에 접근하려고 하기때문
  • 그렇다고 즉시로딩으로 바꿔주기에는 실무에서 적합하지 않다.

해결방안

지금 생각해본 방안은 세가지

  1. SurveyService에서 했던 것처럼, Entity를 DTO로 매핑한 후 컨트롤러에 넘긴다.
    1-1. 문제가 될 수도 있는 부분: Survey 조회 시, N+1 가 발생하고 있어서 그것부터 고쳐야하는데, 그 소스 참고하는 것은 별로인 듯하다.
  2. 컨트롤러에서 프론트에서 받은 파라미터를 우선 서비스로 넘긴후, transaction context 안에서 해결한다.
    2-1. 지금 작성하는 코드가 validation과 거의 다름 없는데, 이미 서비스로 넘기는 것이 별로같음.
  3. JPQL을 사용해서 한번에 조회해오는 메서드를 구현한다.
    3-1. 문법을 찾아봐야한다는거 빼고는 단점은 아직 모르겠다.

JPQL 사용해서 조회하기

참고

profile
갈 길이 멀다
post-custom-banner

0개의 댓글