Hibernate+PostgreSQL环境下分页查询最后一页content返回null
问题根因排查
1. 核心原因:Spring Data 分页页码起始约定不匹配
Spring Data JPA 提供的 Pageable 接口默认页码从0开始计数,你当前总数据量为108条,每页大小设置为10时,有效页码范围为 0~10:
- 当你传入
page=10时,偏移量计算为10 * 10 = 100,查询范围为第101~110条数据,刚好覆盖剩余的8条数据,因此返回正常 - 当你传入
page=11时,偏移量计算为11 * 10 = 110,已经超过总数据量108,理论上应该返回空的内容列表;如果拿到的content为null,大概率是Jackson序列化配置开启了「空集合序列化为null」的规则导致。
2. 次要原因:控制器层判断逻辑错误
你当前代码中的空校验逻辑是完全错误的:Page接口的getSize()方法返回的是请求参数中设置的每页条数,只要你请求时传了size=10,不管当前页有没有数据,这个值永远是10,根本不会触发你写的后续校验逻辑。正确的空判断应该使用reqPage.isEmpty()或者reqPage.getNumberOfElements() == 0。
3. 低概率原因:分页计数查询异常
如果你确认总条数确实是108,可以忽略该原因;如果总条数计算错误,可能是你的自定义查询没有显式指定计数SQL,导致Hibernate自动生成的计数SQL统计结果不准。
修复方案
- 统一前后端页码约定:如果前端习惯页码从1开始,在控制器层接收参数后手动做偏移转换:
Pageable adjustedPage = PageRequest.of( pageable.getPageNumber() - 1, pageable.getPageSize(), pageable.getSort() ); - 修正控制器层的空判断逻辑:
if (reqPage.isEmpty()) { Optional<Business> searchItem = businessService.findById(id); if (searchItem.isEmpty()) { throw new ResourceNotFoundException(); } } - 检查Jackson序列化配置,关闭
SerializationFeature.WRITE_EMPTY_JSON_ARRAYS_AS_NULL配置,保证空内容列表序列化为[]而非null。 - (可选)显式指定Repository查询的计数SQL,避免计数错误:
@Query( value = "SELECT sr FROM Scope sr WHERE sr.business.id = :businessId", countQuery = "SELECT count(sr.id) FROM Scope sr WHERE sr.business.id = :businessId" ) Page<Scope> findByBusinessId(UUID businessId, Pageable pageable);
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

