최대 1 분 소요

문제 상황

Querydsl로 작성한 쿼리에서 페이징을 적용할 경우 count 쿼리를 최적화해주기 위해 별도로 쿼리를 작성해줬는데 반환 값이 0
아닌 null이 되는 바람에 해당 메소드를 사용하는 API를 호출해서 데이터가 없는 페이지에 접근했을 때 500 에러가 발생했다.
다음은 에러가 날 때 코드다.

@Override
public Page<ProductPreviewDto> productWithCategory(Long mallId, Long categoryId, String gender,
                                                    Long filterId, Pageable pageable) {

  List<ProductPreviewDto> content = queryFactory
          .select(new QProductPreviewDto(
                  product.id.as("productId"),
                  product.image.as("productImage"),
                  product.name.as("productName"),
                  product.price,
                  mall.name.as("mallName"),
                  mall.url.as("mallUrl")
          ))
          .from(product)
          .leftJoin(product.category, category)
          .leftJoin(product.mall, mall)
          .where(
                  categoryIdEq(categoryId),
                  genderEq(gender),
                  mallIdEq(mallId)
          )
          .orderBy(filter(filterId))
          .offset(pageable.getOffset())
          .limit(pageable.getPageSize())
          .fetch();

  Long count = queryFactory
          .select(product.count())
          .from(product)
          .leftJoin(product.category, category)
          .where(
                  categoryIdEq(categoryId),
                  genderEq(gender),
                  mallIdEq(mallId)
          )
          .offset(pageable.getOffset())
          .limit(pageable.getPageSize())
          .fetchOne(); // 데이터가 없어 null 반환

  return PageableExecutionUtils.getPage(content, pageable, () -> count);
}

해결

count 쿼리에서 fetchOne() 사용 시 조회되는 데이터가 없는 경우 null을 반환하기 때문에 이에 대한 예외 처리를 해줘야
한다. 때문에 쿼리를 다음처럼 수정해주면서 데이터가 없는 페이지를 조회해도 totalElements0이 되도록 설정할 수 있었다.

Long nullableCount = queryFactory
        .select(product.count())
        .from(product)
        .leftJoin(product.category, category)
        .where(
                categoryIdEq(categoryId),
                genderEq(gender),
                mallIdEq(mallId)
        )
        .offset(pageable.getOffset())
        .limit(pageable.getPageSize())
        .fetchOne();

Long count = nullableCount != null ? nullableCount : 0L;

return PageableExecutionUtils.getPage(content, pageable, () -> count);

카테고리:

업데이트:

댓글남기기