[Spring] Cannot invoke “java.lang.Long.longValue()” because “count” is null
문제 상황
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을 반환하기 때문에 이에 대한 예외 처리를 해줘야
한다. 때문에 쿼리를 다음처럼 수정해주면서 데이터가 없는 페이지를 조회해도 totalElements가 0이 되도록 설정할 수 있었다.
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);
댓글남기기