使用jOOQ从CSV批量导入PostgreSQL时onErrorIgnore与onDuplicateKeyUpdate失效
jOOQ批量导入CSV到PostgreSQL的问题修复
问题1:onErrorIgnore()未跳过错误记录,导入直接终止
onErrorIgnore()默认是单条记录失败时跳过,但jOOQ默认采用批量提交机制,一旦批次内某条记录出错,整个批次会回滚,导致仅错误发生前的批次成功插入。
解决办法:
- 强制单条记录提交,设置
batchSize(1):context.loadInto(table(entityData.getEntityName())) .onErrorIgnore() .batchSize(1) // 每条记录单独处理,出错不影响其他记录 .loadCSV(file) .fields(allFields) .execute() - 也可使用
onErrorLog()自定义错误处理,既能跳过错误记录,还能留存错误详情:context.loadInto(table(entityData.getEntityName())) .onErrorLog(errorCtx -> { System.err.println("导入失败的记录: " + errorCtx.record() + ",错误原因: " + errorCtx.exception().getMessage()); }) .loadCSV(file) .fields(allFields) .execute()
问题2:onDuplicateKeyUpdate()报错,表已配置主键仍提示无主键
报错核心是jOOQ未识别到表的主键元数据,或主键未参与重复判断,常见修复方案:
替换为jOOQ生成的表对象
当前用table(entityData.getEntityName())手动创建表,jOOQ无法获取主键元数据,必须使用jOOQ代码生成器生成的表类:// 示例:假设生成的表类为UserTable context.loadInto(UserTable.USER_TABLE) .onDuplicateKeyUpdate() .loadCSV(file) .fields(allFields) .execute()确保主键字段包含在导入字段中
onDuplicateKeyUpdate()依赖主键判断记录重复,若allFields未包含主键字段,jOOQ无法识别重复依据,需检查并将主键字段加入allFields列表。手动指定冲突的主键字段
若必须使用手动创建的表对象,显式指定冲突的主键字段:// primaryKeyFields为表的主键字段列表,比如Arrays.asList("id") context.loadInto(table(entityData.getEntityName())) .onDuplicateKeyUpdate() .onConflict(primaryKeyFields) .loadCSV(file) .fields(allFields) .execute()
整合后的可用代码示例
// 假设使用jOOQ生成的表对象,且主键已包含在allFields中 context.loadInto(UserTable.USER_TABLE) .onErrorIgnore() .batchSize(1) .onDuplicateKeyUpdate() .loadCSV(file) .fields(allFields) .execute()
内容的提问来源于stack exchange,提问作者Muhamed Risvan M S
相关产品推荐
相关产品推荐

