Spring集成JOOQ3.15+R2DBC查询PostgreSQL报错无法解码OID51968字符串
问题原因分析
该错误本质是PostgreSQL自定义枚举类型的映射问题:PostgreSQL会为每个自定义枚举类型分配独立的OID,你遇到的51968就是目标表中枚举列对应的类型OID。r2dbc-postgresql驱动默认不会自动将自定义枚举类型映射为String,而JOOQ 3.15的R2DBC集成在处理枚举列时,默认调用getString()方法读取值,就触发了类型解码失败。
排查步骤
- 执行SQL
SELECT typname FROM pg_type WHERE oid = 51968;拿到对应的枚举类型名,确认和你表中枚举列的类型一致。 - 检查JOOQ生成的枚举类是否正常,核对生成的枚举值和数据库中枚举定义的取值是否匹配。
解决方案
方案1:配置r2dbc-postgresql驱动识别自定义枚举(推荐)
在R2DBC连接配置中添加extendedEnumTypes参数,注册你的自定义枚举类型即可。比如你查到的枚举类型叫currency_source,就把连接URL修改为:
r2dbc:postgresql://localhost:15432/core_ticker?extendedEnumTypes=currency_source
如果有多个枚举类型需要注册,用逗号分隔即可。该方案不需要改动业务代码,驱动会自动将自定义枚举值解码为String,JOOQ可以正常读取。
方案2:修改JOOQ代码生成配置,强制枚举列转为String类型
在你的Gradle jooq配置的database节点下添加forcedType配置,将枚举列强制映射为String类型:
database.apply { name = "org.jooq.meta.postgres.PostgresDatabase" inputSchema = "public" includes = ".*" excludes = "flyway_schema_history" // 新增以下配置 forcedTypes { create { name = "VARCHAR" includeTypes = "currency_source" // 替换为你实际的枚举类型名 includeExpression = ".*" // 也可以指定具体列,比如currency_rate.source缩小生效范围 } } }
重新生成JOOQ代码后,对应列会变成String类型,不会触发枚举绑定逻辑。
方案3:升级JOOQ版本
JOOQ 3.16及以上版本优化了R2DBC场景下的PostgreSQL枚举映射逻辑,对自定义枚举的兼容性更好,如果业务允许升级依赖版本,直接将jooq版本升到3.16+也可以解决该问题。
内容的提问来源于stack exchange,提问作者Nikita Namestnikov
相关产品推荐
相关产品推荐

