【问题分类】中间件兼容 / 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(支持自动返回主键)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。