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

wlsh44님의 프로필 이미지
wlsh44

작성한 질문수

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

스프링 부트 3.0 findAll() 쿼리

작성

·

969

·

수정됨

5

안녕하세요!!

강의 너무 잘 보고 있는 수강생입니다!

 

스프링 부트 3.0.1 버전으로 프로젝트를 생성해 강의를 듣다가 단순 전체 조회 쿼리(/api/v2/orders)인 findAll()에서 쿼리가 강의와 다르게 나와 궁금증이 생겨 질문 드립니다.

제가 이해하기로는 /api/v2/orders를 호출하면 다음과 같은 순서로 데이터를 가져온다고 생각했습니다.

  1. orders 조회하는 쿼리 호출

  2. OrderDto 를 만드는 과정에서 getMember()getDelivery() 를 호출할 때 Member와 Delivery를 가져오는 쿼리 호출

  3. getOrderItems() 를 통해 orderItems 조회하는 쿼리 호출

  4. OrderItemDto 를 만드는 과정에서 getItem()을 호출할 때 각각의 Item을 가져오는 쿼리 호출

그래서 강의처럼 데이터를 초기화 한다면 총 11번의 쿼리가 발생해야 한다고 생각했고 강의에서도 11번의 쿼리가 생겼습니다.

하지만 제 코드에서는 getDelivery() 를 호출하는 과정에서 이상하게 Delivery를 호출한 후, deliveryId 를 조건절로 Order를 조회하는 쿼리가 한 번 더 생겨 아래 로그처럼 총 13번의 쿼리가 발생했습니다.

 

2023-01-14T18:10:31.860+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.order_date,
        o1_0.status 
    from
        orders o1_0
2023-01-14T18:10:31.890+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        m1_0.member_id,
        m1_0.city,
        m1_0.street,
        m1_0.zipcode,
        m1_0.name 
    from
        member m1_0 
    where
        m1_0.member_id=?
2023-01-14T18:10:31.890+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [1]
2023-01-14T18:10:31.895+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        d1_0.delivery_id,
        d1_0.city,
        d1_0.street,
        d1_0.zipcode,
        d1_0.status 
    from
        delivery d1_0 
    where
        d1_0.delivery_id=?
2023-01-14T18:10:31.895+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [1]
2023-01-14T18:10:31.899+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.order_date,
        o1_0.status 
    from
        orders o1_0 
    where
        o1_0.delivery_id=?
2023-01-14T18:10:31.900+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [1]
2023-01-14T18:10:31.910+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.order_item_id,
        o1_0.count,
        o1_0.item_id,
        o1_0.order_price 
    from
        order_item o1_0 
    where
        o1_0.order_id=?
2023-01-14T18:10:31.910+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [1]
2023-01-14T18:10:31.914+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        i1_0.item_id,
        i1_0.dtype,
        i1_0.name,
        i1_0.price,
        i1_0.stock_quantity,
        i1_0.author,
        i1_0.isbn 
    from
        item i1_0 
    where
        i1_0.item_id=?
2023-01-14T18:10:31.915+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [1]
2023-01-14T18:10:31.916+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        i1_0.item_id,
        i1_0.dtype,
        i1_0.name,
        i1_0.price,
        i1_0.stock_quantity,
        i1_0.author,
        i1_0.isbn 
    from
        item i1_0 
    where
        i1_0.item_id=?
2023-01-14T18:10:31.917+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [2]
==============================================
2023-01-14T18:10:31.919+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        m1_0.member_id,
        m1_0.city,
        m1_0.street,
        m1_0.zipcode,
        m1_0.name 
    from
        member m1_0 
    where
        m1_0.member_id=?
2023-01-14T18:10:31.919+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [2]
2023-01-14T18:10:31.921+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        d1_0.delivery_id,
        d1_0.city,
        d1_0.street,
        d1_0.zipcode,
        d1_0.status 
    from
        delivery d1_0 
    where
        d1_0.delivery_id=?
2023-01-14T18:10:31.921+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [2]
2023-01-14T18:10:31.922+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.order_date,
        o1_0.status 
    from
        orders o1_0 
    where
        o1_0.delivery_id=?
2023-01-14T18:10:31.923+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [2]
2023-01-14T18:10:31.925+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.order_item_id,
        o1_0.count,
        o1_0.item_id,
        o1_0.order_price 
    from
        order_item o1_0 
    where
        o1_0.order_id=?
2023-01-14T18:10:31.926+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [2]
2023-01-14T18:10:31.927+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        i1_0.item_id,
        i1_0.dtype,
        i1_0.name,
        i1_0.price,
        i1_0.stock_quantity,
        i1_0.author,
        i1_0.isbn 
    from
        item i1_0 
    where
        i1_0.item_id=?
2023-01-14T18:10:31.927+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [3]
2023-01-14T18:10:31.928+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL                        : 
    select
        i1_0.item_id,
        i1_0.dtype,
        i1_0.name,
        i1_0.price,
        i1_0.stock_quantity,
        i1_0.author,
        i1_0.isbn 
    from
        item i1_0 
    where
        i1_0.item_id=?
2023-01-14T18:10:31.928+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [BIGINT] - [4]
==============================================

 

혹시나 제가 코드를 잘못 작성했을까봐 강의 자료로 올라온 소스코드에서 default_batch_fetch_size 만 주석 처리하고 스프링 부트 3.0 환경에서 돌려봤는데 같은 결과가 나왔고, JpaRepository 를 통한 findAll 로 두 버전에서 모두 테스트를 해봤는데 같은 결과가 발생했습니다.

 

그래서 Delivery에 @OneToOne으로 걸려있는 order가 문제라 생각해 이 부분을 지우고 실행했더니 해당 쿼리가 사라졌습니다.

 

하지만 @OneToOne의 패치 전략을 Lazy로 하고 따로 Order를 조회하지 않았고, 맨 처음 orders를 조회하는 쿼리를 실행하는 과정에서 영속성 컨텍스트에 orders가 저장 되기도 했기 때문에 해당 쿼리가 생기면 안된다고 생각을 했는데 혹시 제가 잘못 이해하고 있는걸까요..?

 

스프링 부트 3.0으로 올라가는 과정에서 hibernate의 버전도 6으로 올라가 뭔가 변경이 생긴것인지, 아니면 제가 어떤 실수를 하고 있는건지 궁금해서 질문 드립니다..!

답변 2

6

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

안녕하세요. jinhkim님

스프링 부트 3.0 이상을 사용하게되면 하이버네이트6 버전을 사용하게 됩니다.

제 생각에는 하이버네이트 6버전에서 최적화를 못하고 있는 버그라 생각됩니다.

(스프링 관련 이슈가 아닌 것은 확실합니다.)

하이버네이트6에서 OneToOne 관련 이슈들이 조금씩 올라오고 있으니 패치가 될 때 까지는 더 지켜보는 것이 좋을 것 같아요.

이 부분과 관련해서 조금이라도 아시는 분 있으면 공유 부탁드립니다.

감사합니다.

2

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

스프링부트3이상으로 올라가고, 하이버네이트 버전도 변경되면서 발생하는 오류로 보이네요.

자세한 내용은 영한님과 서포터즈가 확인해봐야 알 것 같습니다.

이후 변경되거나 확인되는 내용은 댓글로 공유 드리겠습니다.
.
감사합니다.

강의코드 기준

스프링부트 2.4.x

select

delivery0_.delivery_id as delivery1_2_0_,

delivery0_.city as city2_2_0_,

delivery0_.street as street3_2_0_,

delivery0_.zipcode as zipcode4_2_0_,

delivery0_.status as status5_2_0_

from

delivery delivery0_

where

delivery0_.delivery_id in (

?, ?

)

스프링부트3.0.1

 select

m1_0.member_id,

m1_0.city,

m1_0.street,

m1_0.zipcode,

m1_0.name

from

member m1_0

where

m1_0.member_id in(?,?)

,

select

d1_0.delivery_id,

d1_0.city,

d1_0.street,

d1_0.zipcode,

d1_0.status

from

delivery d1_0

where

d1_0.delivery_id in(?,?)

,

select

o1_0.order_id,

o1_0.delivery_id,

o1_0.member_id,

o1_0.order_date,

o1_0.status

from

orders o1_0

where

o1_0.delivery_id=?

 

implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
wlsh44님의 프로필 이미지
wlsh44

작성한 질문수

질문하기