• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

기본 방식(lazy loading)으로 패치가 되지 않는 문제점

21.07.01 02:14 작성 조회수 190

0

안녕하세요 기선님! 강의 내용을 복습하다가 의문점이 생겨서 질문 드립니다!
@EntityGraph(value="Study.withAll", type = EntityGraph.EntityGraphType.LOAD)
Study findByPath(String path)
이를 통해서 toMany로 끝나는 정보에 대해서는 study 를 조회하는 쿼리에서 한꺼번에 조인을 해서 가져왔었습니다.
그래서 이번에는 역으로 다시 @EntityGraph 를 제거하고 총 다섯번의 쿼리가 발생하는지 확인하였습니다.
애플리케이션도 실행해보고 디버거도 돌려본 결과 쿼리는 5번에 맞게 잘 조회를 하지만, manager 에 대해서는 Lazy Loading에 의해 패치 되지 않았습니다. ( zone 과 tag는 패치가 잘 되었습니다. 그리고 쿼리가 5번 발생한 것으로보아 기본 패치 형태로 Lazy loading도 잘 수행되는 것 같습니다)
account_manager 조인 테이블도 확인한 결과 분명 관계는 설정이 잘 되어 있었는데, 이대로 패치가 되지 않았습니다.
혹시 이 두 관계에 대해서만 패치가 되지 않는 이유가 있을까요?
@EntityGraph를 통해서 study와 함께 한번에 패치 받아올 때는 잘 받아졌습니다!
항상 좋은 강의 감사합니다 :)

답변 3

·

답변을 작성해보세요.

0

김세진님의 프로필

김세진

질문자

2021.07.02

뷰 랜더링 전에 study의 manager 정보를 출력을 해보았습니다.

@GetMapping("/study/{path}")
public String viewStudy(@CurrentUser Account account, Model model, @PathVariable String path){
Study study = studyService.getStudy(path);
model.addAttribute(account);
model.addAttribute(study);

log.info(study.getManagers().toString()); // study Manager 정보가 잘 패치 되는지 확인

return "study/view";
}

lazy loading에 의해서 study 테이블 쿼리 한번, study_manager 테이블 쿼리 한번으로, 쿼리는 정상적으로 출력이 되었습니다.

하지만 당연히 해당 코드에서 에러가 발생하였고,  에러 내용은 다음과 같았습니다.

log.info(study.getManagers().toString());

에러에서는 Large Objects 는 자동 커밋모드에서 사용할 수 없다고 말하고 있습니다!

해당 문제로 인해서 manager 정보가 제대로 패치가 되지 않는 것 같습니다.

다음은 웹페이지 상의 에러입니다!

마찬가지로 lob stream 에 접근할 수 없다고 합니다.

참고로 조인 테이블에는 해당 study에 대한 manager 정보가 잘 저장이 되어있습니다!

managers()."toString()" 이 안에 어떤 코드가 들어있나요? toString()에서 하는 일을 manager의 이름 정도만 출력하는 코드로 바꾸고 다시 실행해 보시겠어요? 어디서 LOB 데이터를 읽어오는 것인지 잘 모르겠네요. LOB 타입의 데이터는 여러 레코드에 저장될 수 있기 때문에 트랜잭션을 사용해서 접근해야 합니다.

김세진님의 프로필

김세진

질문자

2021.07.03

기선님이 말씀하신대로 manager의 이름을 리스트로 출력하는 코드로 테스트를 해보았습니다.

@GetMapping("/study/{path}")
public String viewStudy(@CurrentUser Account account, Model model, @PathVariable String path){
Study study = studyService.getStudy(path);
model.addAttribute(account);
model.addAttribute(study);

log.info(study.getManagersName().toString());

return "study/view";
}
public List<String> getManagersName(){
return this.managers.stream().map(Account :: getNickname).collect(Collectors.toList());
}

하지만 마찬가지로 동일한 에러가 발생하는 것을 알 수 있었습니다. 

manager 정보를 lazy로 가져오지 않고, @EntitiyGraph를 통해서 EntityGraph.EntityGraphType.LOAD 타입으로 가져왔을 때는  이상이 없었습니다!

이 두 차이점으로 인한 원인을 찾으려고 하고 있으나 아직 제 지식이 부족한 것 같습니다 

더 학습하면서 해결해보도록 하겠습니다 : )

0

김세진님의 프로필

김세진

질문자

2021.07.01

안녕하세요. 기선님!

제가 질문할때 오타가 있었네요. account_manager 테이블이 아니라 study_manager 테이블이었습니다.

질문 게시글과 마찬가지로 study_manager 테이블에  해당 study에 대한 manager 객체가 존재하는데도 패치가 되지 않았었습니다!

동일한 study_manager 테이블에 대해서 @EntitiyGraph를 통해서 study 객체와 한번에 전부 패치 받을때는 잘 받아와지는데 Lazy loading으로는 패치가 안되었네요!

0

안녕하세요. 해당 스터디와 관련있는 manager에 대한 데이터가 없기 때문에 lazy loading을 하지 않은것으로 보입니다. tag나 zones 처럼 데이터를 추가하고 다시 해보시겠어요?