인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김세진님의 프로필 이미지
김세진

작성한 질문수

스프링과 JPA 기반 웹 애플리케이션 개발

스터디 조회

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

작성

·

261

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

김세진님의 프로필 이미지
김세진
질문자

뷰 랜더링 전에 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 타입의 데이터는 여러 레코드에 저장될 수 있기 때문에 트랜잭션을 사용해서 접근해야 합니다.

김세진님의 프로필 이미지
김세진
질문자

기선님이 말씀하신대로 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

김세진님의 프로필 이미지
김세진
질문자

안녕하세요. 기선님!

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

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

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

0

백기선님의 프로필 이미지
백기선
지식공유자

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

김세진님의 프로필 이미지
김세진

작성한 질문수

질문하기