inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

주문 조회 V2: 엔티티를 DTO로 변환

ordersV2(url : api/v2/orders) 실행 시 쿼리 질문

해결된 질문

453

tksrleo123

작성한 질문수 6

1

실행창을 확인해보니 해당 API 호출 시 쿼리가

order -> member -> delivery -> orderitems -> item -> (2) -> item -> ( 1 ) ->member -> delivery -> orderitems ->item -> (2)->item

 

순으로 나갑니다.

(1)에 두 번째 order 을 조회하는 쿼리가 나가야 하지않나요?

  1. 처음 findAllByString 메서드로 두 개의 Order 모두 로딩했다.

  2. 처음 로딩한 Order 을 1차캐시에서 가져왔다.

 둘 중 뭐가 맞는지 궁금합니다.

 다음으로

(2) 에는 orderitem 이 조회 된다고 생각했었는데 왜 한번만 조회 된 후 item이 두 번 조회되는건지 궁금합니다.

 

 

다음으로

orderItem 이 로딩되는 시점은 orderItem.getItem()

이고

Item의 로딩 시점은 orderItem.getItem().getName(); 이라고 알고 있는데 맞는지 궁금합니다.

= 로딩이 '해당객체'의 조회 시점인지 '해당객체의 필드에 접근' 하는 시점인지 궁금합니다.

 

 

spring spring-boot java JPA

답변 1

0

y2gcoder

안녕하세요. tksrleo123님, 공식 서포터즈 y2gcoder입니다.

우선 말씀해주신 것을 보니 강의 자료 상

image이 부분을 말씀하신다고 이해하고 설명드리겠습니다.

 

(1) order들은 이미 findAll() 때 query를 통해 order를 다 가져온 상황입니다. 그래서 다시 order를 부를 필요가 없습니다.

(2) 이 때는 dto에서 프록시가 초기화되는 순서를 보셔야 합니다.

image

위의 OrderDto의 생성자 부분에서 orderItems 부분을 봐주시겠습니까?
그리고 말씀하신 것처럼 orderItems 의 프록시를 초기화할 때 발생하는 SQL 문을 봐주시면

imagewhere 조건에서 해당 orderItem 하나만 들고오는 것이 아니라 order_id를 이용해 해당 orderItems를 전부 가져왔습니다.
따라서 (2)에서 다시 orderItem을 불러오지 않습니다. 왜냐하면 이미 orderItem들을 다 갖고 있기 때문입니다.


감사합니다.

0

tksrleo123

image답변감사합니다!!!

 

그렇다면 혹시 orderitem 두개를 가져오는 순간은 order.getOrderItems() 이때 인가요? 아니면 .stream() 을 열 때 가져오나요?

저는 프록시객체를 초기화 시키는 타이밍이 해당 객체에 접근 할 때 라고 알고 있어서 orderitem의 필드에 접근 할 때로 이해했습니다.

image처음에는 OrderItemDto에서 orderItem.getItem() 순간에 orderitem이 초기화 되는 줄 알았지만 orderItem이 두 개가 동시에 초기화 되는 것으로 보아 이 부분은 제외했습니다.(stream이라 1개씩 초기화 되는 것으로 생각했습니다!)

0

y2gcoder

저도 사실 궁금해서 디버깅이랑 로깅을 통해서 실험을 해봤더니, 말씀하신대로 order.getOrderItems().stream().map().collect(toList()); 부분에서 SQL이 나가는 것을 확인했습니다. 아마 stream 의 동작방식과 관련이 있는 것 같은데 먼저 리스트를 형성하고 map을 이용해서 dto를 만들어서 넣기 전에 orderItem 첫 원소를 불러오는 과정에서 sql이 날아가는 것 같습니다.
혹시나 눈으로 보길 원하신다면 강의 소스를 디버깅으로 켜시고 브레이크포인트를 걸어서 확인해보시면 재밌을 것 같습니다!

0

tksrleo123

아하 디버깅까지 해주시다니.. 정말 감사합니다! stream은 최종 연산까지 동작을 지연시키는 걸 잊고있어서 헷갈렸네요! 저도 디버깅 직접 해보겠습니다 꿀팁 감사합니다!

0

y2gcoder

저도 질문해주신 덕분에 잘 배웠습니다 감사합니다 :)

강의 관련 외 질문입니다.

0

82

2

SpringBoot4 + Hibernate7 모듈 등록 방법 공유

1

101

1

BeanCreationException

0

96

3

Update 후 UpdateMemberResponse 매핑할 때

0

57

1

트랜잭션을 사용 안 할 때 커넥션은 언제 가져오나요?

0

103

2

페이징 + 검색조건 관련해서 질문드립니다.

0

74

1

Query Dsl Q파일 질문입니다.

0

86

1

루트 쿼리라는것은

0

62

1

메서드를 분리하는 기준

0

71

1

findAllWithMemberDelivery 메서드 질문드립니다.

0

116

3

연관관계 매핑을 안 쓸 경우, 사용해야 하는 전략

0

92

2

fetch join과 영속화와 OSIV의 관계

0

91

2

Distinct 사용 전 결과에 대한 의문

0

120

2

레포지토리 계층에서의 트랜잭션에 대한 의문

0

63

1

영속성 컨텍스트 생명주기의 신기한 부분이 있습니다.

0

79

2

dto 필드 속 엔티티 여부

0

63

1

뷰템플릿 사용 시

0

82

2

Result 클래스 관련 질문

0

57

1

@PostConstruct 프록시 관련 질문드립니다

0

88

1

DTO 대신 Form 사용은 안되나요?

0

140

1

OSIV ON 상태일 때

0

99

1

fetch join VS fetch join 페이징 궁금증

0

191

2

양방향 연관관계 알아보는 법?

0

110

1

16강 17강 간단 정리 이게 맞을까요 ?

0

168

2