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

맥북유저님의 프로필 이미지
맥북유저

작성한 질문수

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

default_batch_fetch_size: 100 으로 설정을 해줘도 쿼리가 한번에 가져오지 않습니다.

작성

·

499

·

수정됨

0

    @GetMapping("api/v2/orders/{id}") // batch_fetch_size 검색용
    public ResultMany findByBatchFetch(@PathVariable("id") Long id) {
        Customer customer = customerService.findCustomerById(id);
        List<Order> orders = orderRepository.findAllOrder();
        return getOrderDtoList(orders);
    }

 

    public List<Order> findAllOrder() {
        return em.createQuery("select o from Order o", Order.class)
                .getResultList();
    }

 

private ResultMany getOrderDtoList(List<Order> orders) {
    List<OrderDto> orderDtos = orders.stream()
            .map(o -> new OrderDto(o))
            .collect(Collectors.toList());
    return new ResultMany<>(orders.size(), orderDtos);
}

 

@Data
static class OrderDto {
    private Long id;
    private CustomerDto customer;
    private List<DiffuserProductRequestDto> diffuserProductRequest;
    public OrderDto (Order order) {
        id = order.getId();
        customer = new CustomerDto(order.getCustomer());
        diffuserProductRequest = order.getDiffuserProductRequests().stream()
                .map(diff -> new DiffuserProductRequestDto(diff))
                .collect(Collectors.toList());
    }
}

 

@Data
static class DiffuserProductRequestDto {

    private Long id;

    private DiffuserDto diffuser;

    private int amount;

    private Deadline deadline;

    private ProductionStatus status;

    public DiffuserProductRequestDto (DiffuserProductRequest diffuserProductRequest) {
        id = diffuserProductRequest.getId();
        diffuser = new DiffuserDto(diffuserProductRequest.getDiffuser());
        amount = diffuserProductRequest.getAmount();
        deadline = diffuserProductRequest.getDeadline();
        status = diffuserProductRequest.getStatus();
    }
}

 

 

위에는 order클래스 연관된 클래스를 찾기위한 코드들인데 제가 27개의 오더를 만들고 get요청을 보내면 default_batch_fetch_size: 100으로 설정 해놓았기 때문에 27개를 한번에 가져올 것이라고 생각하고 있는데 결과는 그렇지 않습니다

스크린샷 2023-09-15 오후 5.21.34.png

스크린샷 2023-09-15 오후 5.21.40.png

이렇게 두번의 쿼리로 찾아오는데 어떤게 문제인걸까요?

답변 2

0

안녕하세요. 맥북유저님, 공식 서포터즈 y2gcoder입니다.

default_batch_fetch_size 에 대한 하이버네이트의 최적화 방식과 관련이 있습니다!
다음 링크(클릭)을 참고해주십시오!

 

감사합니다.

맥북유저님의 프로필 이미지
맥북유저
질문자

감사합니다!

 

0

안녕하세요, 인프런 AI 인턴이에요.
default_batch_fetch_size를 설정하면 한 번에 가져오기 위한 쿼리 횟수를 지정하는 것인데, 여러 번의 쿼리 실행으로 인해 원하는 결과가 나타나지 않는 경우에는 다음과 같은 사항을 확인해 볼 수 있어요.

  1. 엔티티 클래스와 관련한 fetch 방식 설정 확인하기:
    엔티티 클래스 내부에서 연관관계(fetch)를 어떤 방식으로 설정하였는지 확인해 볼 필요가 있어요. 예를 들어, @OneToMany(fetch = FetchType.LAZY)로 설정되어 있다면, 실제로 해당 컬렉션을 사용할 때까지 초기화를 지연하는 방식이기 때문에 일부 쿼리를 추가로 실행할 수 있습니다. 이 경우에는 @BatchSize 애노테이션을 사용하여 성능을 향상시킬 수 있습니다.

  2. JPA 설정 확인하기:
    JPA 프로바이더에 따라 default_batch_fetch_size 설정이 올바르게 동작하지 않을 수 있습니다. 해당 프로바이더에 맞게 설정을 확인해보세요.

  3. 지연 로딩 확인하기:
    연관된 엔티티가 지연 로딩으로 설정되어 있다면, 해당 엔티티를 사용할 때마다 추가 쿼리를 실행할 수 있습니다. 이 경우 fetch 방식을 변경하거나 fetch join을 활용하여 한 번에 가져올 수 있도록 설정할 수 있습니다.

위의 사항들을 확인해 보시고 문제가 해결되지 않으면 관련 코드나 설정 정보를 더 자세히 알려주시면 더 구체적인 도움을 드릴 수 있을 것 같아요.

맥북유저님의 프로필 이미지
맥북유저

작성한 질문수

질문하기