使用Blaze-Persistence分页时返回的分页元数据结果错误如何解决
问题根因
- BlazeJPAQuery 1.5.0以下版本的
fetchResults()方法在处理带group by的查询时,自动生成的count查询逻辑存在缺陷:默认直接将原查询的select子句替换为count(*),不会保留group by逻辑,最终统计的是join后原始表的总行数,而非聚合后的分组总数,导致result.getTotal()返回值错误。 - 代码存在变量引用不一致问题:你已定义
StringPath name = qTax.name,但groupBy子句中使用的是未在代码片段中声明的taxName变量,若该变量绑定的字段路径和qTax.name不一致,会导致聚合分组逻辑异常,进一步干扰总数统计。 - 分页参数计算逻辑不兼容:Spring Data的
PageRequest.of(pageNo, pageSize)默认pageNo从0开始计数,如果你业务中传入的pageNo是从1开始的,你写的offset(pageNo * pageSize)会导致分页偏移量计算错误,也会表现为总页数、返回结果匹配异常。
修复方案
修正变量引用错误
将groupBy(taxName, groupBy)改为groupBy(name, groupBy),确保分组字段和查询字段绑定一致。手动统计聚合后的总条数(最稳妥方案)
放弃fetchResults()的自动count逻辑,单独编写count查询统计分组总数,再手动组装Page对象,代码参考如下:
// 先统计聚合后的总分组数 Long total = new BlazeJPAQuery<>(em, cbf) .from(qTax) .innerJoin(qOrderDetails).on(qTax.orderDetails.eq(qOrderDetails)) .groupBy(name, groupBy) .fetchCount(); // 再查询当前页的数据 List<TaxDto> results = new BlazeJPAQuery<>(em, cbf) .select(Projections.constructor(TaxDto.class, fromDate, toDate, groupBy, name, totalTaxValue, ordersCount)) .from(qTax) .innerJoin(qOrderDetails).on(qTax.orderDetails.eq(qOrderDetails)) .groupBy(name, groupBy) .orderBy(groupBy.asc(), name.asc()) .offset(pageNo * pageSize) // 若pageNo从1开始,改为 (pageNo - 1) * pageSize .limit(pageSize) .fetch(); // 手动组装分页对象 Page<TaxDto> p = new PageImpl(results, PageRequest.of(pageNo, pageSize), total);
- 版本升级方案
如果你要继续使用fetchResults(),请将Blaze-Persistence版本升级到1.5.0及以上,该版本修复了带group by查询的count自动生成逻辑,会自动包裹子查询统计分组总数,无需额外修改代码。
内容的提问来源于stack exchange,提问作者java dev
相关产品推荐
相关产品推荐

