【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
问题现象
BeetISQL中间件版本:2.13.8.RELEASE
客户在调用BeetISQL提供的api向yashandb的表中执行batch insert并将返回sequence设置到传入的java bean时,报如下异常:
问题的风险及影响
影响业务流程正常执行,无法获得batch insert所关联数据库记录设置的sequence id。
对此业务流程的解释说明:
-
某表有两列,分别为tid(数据类型number), tname(数据类型varchar2)。其中tid不需要业务传入,其值应由另外一个yashandb的sequence自动生成。
-
此表对应的java bean名称为TestTable,业务流程在调用batchInsert(List
)时,list中的元素的tid都没有值,实际给yashandb下发的sql语句为insert into test_table(tid,tname) values(sequence.nextval, ?)。 -
batchInsert完成后,业务在遍历List
时,其元素的tid已经由中间件经过jdbc提供的接口获取并设置回来了。
问题影响的版本
与yashandb版本无关
问题发生原因
beetlsql在此种batch insert情况下,prepareStatement的时候调用的是conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 没有指定返回哪一列。
yashan jdbc驱动会返回生成的rowid(字符串类型),而java bean和数据库中表对应列(tid)是数字型,从字符串向数字型转换的时候,出了异常。
解决方法及规避方式
在batchInsert时,不返回自动生成的sequence id值 或者 升级到BeetISQL 3
问题分析和处理过程
根据现网实际表结果,在yashandb中创建测试表及sequence:
create table test_entity(
tid number primary key not null,
age number,
name varchar2(30),
create_date date
);
create sequence seq_id;
然后搭建java工程进行问题重现并打断点分析。结合关键日志:
insert into YAOWEI.TEST_ENTITY
(TID,AGE,NAME,CREATE_DATE) VALUES (seq_id.nextval,?,?,?) RETURNING ROWID INTO ?
中的returning rowid,判断出是在将rowid转换为数字的时候出的问题。
在BeetISQL 2中的规避方案就是将insertBatch中的autoDbAssignKey参数由true改为false。
BeetISQL 3中的关键源码已经修改,为conn.prepareStatement(result.jdbcSql, this.getKeyHolderCols(holder, entity.getClass()));
此时可以正常返回sequence.nextval
经验总结
如下为可直接运行的beetsql 2及3 demo:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库