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

원석나님의 프로필 이미지
원석나

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

간단한 주문 조회 V1: 엔티티를 직접 노출

Hibernate5Module가 기본상태일때

작성

·

481

3

하이버네이트 모듈이 기본상태일때 orderItem을 DB에서 자꾸 쿼리하는게 로그상에 보여서 질문드리는데요

이 상태에서 Order엔티티에  "orderItems" 는 1대다 관계로 묶여있어서 당연히 기본이 lazy로딩이라서 orderItems에 접근하지 않는한 DB에서 쿼리하지 않을줄 알았는데  쿼리가 나가더라구요 ..?  왜 그런걸까요 ..?? 제가 배운 내용으로는 이해가 가지 않아서 ㅠㅠ 

답변 4

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요.

코드를 확인해보니 getTotalPrice()에 범인이 있었네요.

public int getTotalPrice() {
int totalPrice = 0;
totalPrice = orderItems
.stream()
.mapToInt(OrderItem::getTotalPrice)
.sum();

JSON을 생성할 때 getXxx를 호출하는데요. 이때 getTotalPrice 메서드를 호출하게 됩니다.

여기에서 orderItems가 직접 사용되고 있습니다.

감사합니다.

원석나님의 프로필 이미지
원석나
질문자

강사님 코드 봐주시느라  너무너무 고생 많으셨습니다 정말 감사합니다 ㅠㅠ

그  잭슨??  그 라이브러리가 json형태로 만들때  

메소드이름에 get이 들어간건 모두 호출한다는 말씀이실까요??  그렇다면 게터 역시 호출의 대상이 되나요?

================================================================================================================================================================================================

제가 해보니깐 사진과 같이 조회하는 엔티티 안에 메소드 이름에 "get" 이 들어가고 리턴값이 있다면 호출이 되더라구요 ㅎㅎ 

제가 테스트한 내용이 위에 질문에 대한 대답이 되는걸까요?

김영한님의 프로필 이미지
김영한
지식공유자

네 맞습니다. getXxx를 찾아서 Json을 생성합니다.

감사합니다.

0

저도 강의 듣다가 요부분이 궁금 했었는데 덕분에 해결되었네요. 감사합니다 :)

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 원석나님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

원석나님의 프로필 이미지
원석나
질문자

드라이브 링크 입니다 !

https://drive.google.com/drive/folders/1Iq4fQOj1nErHq9EdpQNZyHgukHpr3XMp?usp=sharing  

1. 실행방법

     - jpashopapplication 을 실행 시키신 후  postman이나 api 요청하는 도구를 사용하셔서

        http://localhost:8080/api/v1.1/simple-orders 로 요청 하시면 됩니다!

(해당 메소드는 jpabook - jpashop - api - OrderSimpleApiController  에  ordersV1_1 메소드입니다!

2. 문제확인법

- api요청 후 로그를 보시면 orderItems 관련 쿼리가 2번 나간걸 확인하실수 있습니다.

메소드의 리턴타입을 void로 두시고 return을 없앤후 다시 요청해보시면 orderItems 관련 쿼리가 안나가는걸 확인 하실 수 있습니다.

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 원석나님

정확하게 어떤 시점에 해당로그가 출력되는지 먼저 확인해보시겠어요?

로직 위아래로 system.out.println("...")을 출력해서 그 시점을 먼저 찾아서 확인해주세요.

감사합니다.

원석나님의 프로필 이미지
원석나
질문자

일단 repository에서 findAllByString()에서는 JPQL 쿼리만 SQL로 번역되서 나갔지 OrderItem에 관한 쿼리는 안나가는 것으로 확인되었습니다.

orderItem에 대한 쿼리가 return all 이후에 나가는거 같은데 정확히 어디서 나가는지는 찾질 못하겠습니다 ..

=============================================================================================

추가적으로 정확히 좀 알고 싶어서 제가 좀 억지로 메소드를 작성해서 테스트 해봤는데요!! 

이렇게 리턴이 없을때는 orderItem에 대한 쿼리가 안나가고

Order를 리턴해주거나 List<Order>를 리턴해줄때 OrderItem쿼리가 나가는것으로 확인 되었습니다.

근데 이유를 잘 모르겠습니다.. 리턴해줄때 OrderItem 프록시에 접근을 하는건지 ..

만약 접근 한다면 왜 지연로딩으로 설정된 다른 필드들은 안그러고 OrderItem만 그러는지 파악이 안됩니다

원석나님의 프로필 이미지
원석나

작성한 질문수

질문하기