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

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

작성자 없음

작성자 정보가 삭제된 글입니다.

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

현재 상황에서 OrderItem에 대한 조회가 왜 일어나는 지 잘 모르겠습니다.

작성

·

166

0


[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 네
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네
3. 질문 잘하기 메뉴얼을 읽어보셨나요?네

[질문 내용]

안녕하세요 영한 선생님!! 강의 잘 보던 중 의문이 생겨 질문이 드립니다.
 
/api/v3.1/orders를 만드는 과정에서 (batch size 적용)
 
batch size 적용 후 OrderItem에 대해 쿼리가 나가는 시점(Lazy가 적용이 되는 것인지)을 명확하게 모르겠어서 도메인을 DTO로 변환하지 않고 직접 도메인을 반환하도록 약간의 수정을 해봤는데요!
 
api 코드입니다.

@GetMapping("/api/v3.1/orders")
public List<Order> ordersV3_page(
@RequestParam(value="offset", defaultValue = "0") int offset,
@RequestParam(value="limit", defaultValue = "100") int limit )
{
List<Order> orders = orderRepository.findAllWithMemberDelivery(offset, limit);


// List<OrderDto> collect = orders.stream()
// .map(o -> new OrderDto(o))
// .collect(Collectors.toList());

return orders;

}
 
Repository 코드입니다.
public List<Order> findAllWithMemberDelivery(int offset, int limit) {
return em.createQuery(
"select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class)
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList();
}
 
/api/v3.1/orders 조회 쿼리입니다.
조회 response입니다.
 
[
    {
        "id": 4,
        "member": {
            "id": 1,
            "name": "userA",
            "address": {
                "city": "서울",
                "street": "1",
                "zipcode": "1111"
            }
        },
        "orderItems": null,
        "delivery": {
            "id": 5,
            "address": {
                "city": "서울",
                "street": "1",
                "zipcode": "1111"
            },
            "status": null
        },
        "orderDate": "2022-01-19T20:14:36.130898",
        "status": "ORDER",
        "totalPrice": 30000
    },
    {
        "id": 11,
        "member": {
            "id": 8,
            "name": "userB",
            "address": {
                "city": "진주",
                "street": "2",
                "zipcode": "2211"
            }
        },
        "orderItems": [
            {
                "id": 13,
                "item": null,
                "orderPrice": 20000,
                "count": 2,
                "totalPrice": 40000
            },
            {
                "id": 14,
                "item": null,
                "orderPrice": 80000,
                "count": 4,
                "totalPrice": 320000
            }
        ],
        "delivery": {
            "id": 12,
            "address": {
                "city": "진주",
                "street": "2",
                "zipcode": "2211"
            },
            "status": null
        },
        "orderDate": "2022-01-19T20:14:36.161899",
        "status": "ORDER",
        "totalPrice": 360000
    }
]
 
그럼 의문 사항인데요,
 
도메인을 직접적으로 반환하는 과정에서
 
1. OrderItem에 직접적으로 접근하지 않았고, Order entity에 정의된 OrderItem은 Lazy Loading인데 왜 OrderItem에 대한 조회 쿼리가 발생했는지 잘 모르겠습니다.
 
2. OrderItem에 대한 조회 쿼리가 발생했음에도 불구하고 왜 Order Id 11은 OrderItem이 조회가 되고 Order Id 4에 대한 OrderItem은 여전히 Null로 조회되는지 잘 모르겠습니다.
 
소스 코드 링크입니다. (문제 상황이 도출되도록 수정이 되어있습니다.)
https://drive.google.com/file/d/1cLs3su4q1R2iIJPAe3K9pral-SqhMKk9/view?usp=sharing
 
포스트맨을 통해 /api/v3.1/orders 를 실행했을 때 일어나는 현상입니다.
 
 
답변주시면 감사하겠습니다!!! 강의 내용이 너무 도움이 되고 있습니다.

답변 1

0

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

안녕하세요. 유호성님

default_batch_fetch_size 옵션을 끄고 테스트해보시면 왜 이렇게 동작했는지 이해가 되실거에요.

추가로 이 옵션을 꺼도 orderitem을 조회하는 쿼리가 실행은 되는데, 이것은 JSON을 만드는 라이브러리에서 해당 코드를 건들기 때문에 프록시 초기화가 발생하는 듯 합니다.

실무에서는 API 응답은 엔티티를 직접 반환하지 않기 때문에(DTO로 변환해서 반환) 이런 문제는 크게 고민하지 않으셔도 됩니다.

감사합니다.

감사합니다!!!

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기