DEBUG.WIKI
雨云;给项目一台云服务器
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关

jOOQ SEEK 分页突然返回空页,检查 noField 与冗余条件

SEEK 首位用 noField 跳过游标比较,又开启冗余条件时,生成的 a >= NULL 会让整页被过滤。保留分页意图,先关闭该优化再核对 SQL。

SEEK 分页的第一页有数据,传入游标后却突然得到空页。检查渲染 SQL 时,如果看到下面这样的条件,先排查 noField 与冗余 SEEK 条件的组合:

where (a >= null and b > 2)

a >= NULL 的结果是 UNKNOWN,WHERE 不会保留该行。此时增加页大小、换连接池或重建索引,都不能把这条条件变成原来想要的游标比较。

哪种配置会触发

相关路径需要同时满足:排序包含多个字段;SEEK 第一项使用 noField(...);开启了 renderRedundantConditionForSeekClause;首个排序字段没有显式 NULL 排序。

例如,orderBy(a, b).seek(noField(a), inline(2)) 表示第一项不参与相应游标比较。主 SEEK 条件会跳过这个标记,但受影响的冗余条件生成路径仍用第一项与排序字段比较,额外带入 NULL。

这个问题在3.22开发快照中被明确指出,正式3.21.9的相应代码也保留了同样的判断。不能仅凭标题中的开发版本,就认定正式依赖一定没有这条路径;也不能把所有空页都归到它。没有 noField 或没有那条 >= NULL 时,应继续检查实际参数、过滤条件和排序。

先关闭这项优化,保留原分页设计

如果当前查询依赖跳过首个 SEEK 项,可以在该查询使用的配置中关闭冗余条件:

在项目现有的查询配置入口,将 renderRedundantConditionForSeekClause 设为 false。若只有这一条查询需要调整,应复制现有设置并派生独立配置,保留原有方言、绑定、连接及其他选项,不要原地修改其他请求共用的设置。

这会移除用于帮助查询规划器的冗余比较,不是关闭真正的 SEEK 条件。仍需查看最终 SQL,确认错误的 NULL 比较消失、需要的游标条件还在,并评估该查询的执行计划。

不要把 noField 机械替换成 SQL NULL,也不要填入随意的最小值来让查询返回数据。前者仍有 NULL 比较语义,后者可能改变分页边界。如果业务实际上需要比较第一项,应传入真实游标值,并重新确认整个排序键的唯一性。

按跨页结果验收

准备包含相同首排序值、不同次排序值的测试数据,覆盖正向与反向分页、页边界及重复值。核对 SQL 和连续页的合并结果,检查有没有漏行或重复行;只看到空页变成非空页还不够。

修复已进入后续版本目标,包括3.21.10,但截至2026年10月25日核对的正式tag仍到3.21.9。采用后续包之前,应确认真实发布版本及其代码,不把已关闭的问题状态当成当前依赖已经修复。