写点什么

YashanDB 知识库|BeetISQL 批量插入时报 autoAssignKey 异常? 可能是 rowid 惹的祸

作者:数据库砖家
  • 2025-04-22
    广东
  • 本文字数:953 字

    阅读完需:约 3 分钟

【问题分类】中间件兼容 / JDBC 集成异常

【关键词】JDBC、BeetISQL、batchInsert、RETURN_GENERATED_KEYS、rowid、类型转换异常

一、问题现象

某项目中集成 BeetISQL 2.13.8.RELEASE 版本,在通过 API 调用批量插入接口(batchInsert)并希望自动回填数据库生成的 sequence 值时,出现如下异常:

autoAssignKey failure

该错误会直接中断业务流程,使得批量插入操作无法正常获取数据库生成的主键 ID。

二、场景说明

目标表结构:

create table test_entity (tid number primary key not null,tname varchar2(30));create sequence seq_tid;
复制代码

Java Bean 示例(TestTable):

class TestTable {private Long tid;private String tname;}
复制代码

插入逻辑: 通过 batchInsert(List) 批量插入数据,其中 tid 字段由数据库 sequence 自动生成,未在 Java Bean 中提前赋值。

三、问题根因分析

现象定位:

在 BeetISQL 2.x 中,底层 JDBC 使用如下方式构建 PreparedStatement:conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
复制代码

此时未明确指定返回哪一列的 key。

实际效果:

YashanDB 的 JDBC 驱动会默认返回 ROWID(为字符串类型);

而业务中的 tid 字段为 NUMBER 类型;

导致中间件在将 ROWID 赋值给 tid 时,因类型不匹配(String → Long)触发异常。

四、适用版本

与 YashanDB 驱动版本无关;

主要影响 BeetISQL 2.x 系列版本;

BeetISQL 3.x 已修复此问题。

五、解决方案

方法一(推荐):升级至 BeetISQL 3.x

BeetISQL 3 中已修复此问题:

conn.prepareStatement(sql, this.getKeyHolderCols(holder, entity.getClass()));
复制代码

可正常返回指定列的 sequence.nextval 值,类型转换无误。

方法二:禁用自动主键赋值(适用于 BeetISQL 2.x)

在调用 insertBatch() 时,将 autoAssignKey 参数设置为 false:

sqlManager.insertBatch(TestTable.class, dataList, false);
复制代码

这样可以避免中间件自动尝试获取返回主键值,规避类型转换异常。

六、测试与验证过程

通过构造如下 SQL 模拟操作:

insert into TEST_ENTITY (tid, tname) values (seq_tid.nextval, ?)returning rowid into ?
复制代码

实际调试中可观察到返回的 rowid 类型为字符串,触发 autoAssignKey failure 的栈信息位于 key 映射阶段。

七、总结与建议

附:官方测试样例

beetlsql_2_demo(关闭自动返回主键)

beetlsql_3_demo(支持自动返回主键)

用户头像

还未添加个人签名 2025-04-09 加入

还未添加个人简介

评论

发布
暂无评论
YashanDB知识库|BeetISQL 批量插入时报 autoAssignKey 异常?可能是 rowid 惹的祸_数据库·_数据库砖家_InfoQ写作社区