使用PostgreSQL returning子句时出现意外PSQLException
问题解决:PostgreSQL + jOOQ INSERT RETURNING 抛出"A result was returned when none was expected"异常
问题分析
从异常堆栈和生成的SQL可以看出:
- 执行的INSERT语句带有完整RETURNING子句,会返回插入后的完整记录
- PostgreSQL驱动检测到代码调用了
executeUpdate()(用于无结果的DML操作),但实际有结果集返回,因此抛出异常 - jOOQ误将带RETURNING的INSERT语句当作普通更新执行,核心原因是语句执行策略的判断逻辑异常
解决方案
方案1:使用UpdatableRecord的store()方法(推荐)
既然已经生成了VendorRecord,直接调用其store()方法会自动处理插入逻辑,且能正确适配PostgreSQL的RETURNING特性,无需手动构建INSERT语句:
public Vendor insert(final Vendor pojo) { final VendorRecord record = dsl.newRecord(VENDOR, pojo); record.setDateCreated(OffsetDateTime.now()); record.setCreatedBy("TODO"); record.store(); // 自动执行INSERT并获取返回的完整记录 return record.into(Vendor.class); }
方案2:调整INSERT语句的RETURNING写法
替换returning(VENDOR)为无参数的returning(),让jOOQ正确识别需要处理结果集:
public Vendor insert(final Vendor pojo) { final VendorRecord record = dsl.newRecord(VENDOR, pojo); record.setDateCreated(OffsetDateTime.now()); record.setCreatedBy("TODO"); return dsl .insertInto(VENDOR) .set(record) .returning() // 自动返回所有字段,替代returning(VENDOR) .fetchOneInto(Vendor.class); }
方案3:确认SQL方言配置
确保Spring Boot中正确配置PostgreSQL方言,避免jOOQ使用通用方言导致执行逻辑错误:
# application.properties spring.jooq.sql-dialect=POSTGRES
额外说明
vendor表中enabled和version字段带有默认值,插入时无需手动设置,上述方案均能正确获取这些默认值并映射到Vendor对象中。
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

