JPA操作CosmosDB带排序分页时requestContinuation返回空结果问题
解决方案
- 首先修正
CosmosPageRequest的页码参数:带排序的分页请求,携带前一次返回的requestContinuation发起下一页请求时,页码参数需要传入当前请求的实际页号(首次请求是第0页,第二次请求要传1,以此类推),不要固定传0。不带排序的分页对页码参数校验宽松,所以可以正常返回结果,但带排序的复合token结构依赖页码连续性校验,传0会被判定为请求第一页,结合token就会返回空结果。 - 不要对返回的
requestContinuation做任何手动处理:你看到的转义符\是字符串序列化输出(比如日志打印、控制台输出)时的转义标识,实际JVM内存中存储的token字符串不存在这些转义符,直接调用分页结果对象的getContinuationToken()方法拿到原始值传入下一次请求即可,手动去转义、编码、修改结构都会导致token失效。 - 检查Spring Data Azure Cosmos DB依赖版本:3.0.0~3.17.0版本存在带ORDER BY查询的复合continuation token解析已知bug,如果是上述版本区间,升级到3.18.0及以上稳定版,或者4.x最新版本即可修复。
- 确保每次请求的排序规则完全一致:排序字段、排序方向(ASC/DESC)、排序字段的顺序都要和首次请求完全相同,任意一处调整都会导致之前的token失效。
正确代码示例:
// 首次请求 int pageSize = 5; Sort sortRule = Sort.by(Sort.Direction.DESC, "createTime"); CosmosPageRequest firstPageReq = CosmosPageRequest.of(0, pageSize, sortRule); CosmosPage<YourEntity> firstPage = repo.findAllByUserId(userId, firstPageReq); List<YourEntity> firstPageData = firstPage.getContent(); // 5条数据 String nextToken = firstPage.getContinuationToken(); // 直接获取原始token,不做任何处理 // 第二次请求 CosmosPageRequest secondPageReq = CosmosPageRequest.of(1, pageSize, nextToken, sortRule); CosmosPage<YourEntity> secondPage = repo.findAllByUserId(userId, secondPageReq); List<YourEntity> secondPageData = secondPage.getContent(); // 剩余3条数据
内容的提问来源于stack exchange,提问作者Cristian
相关产品推荐
相关产品推荐

