You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot整合Oracle时JSON数字格式字符串无法入库问题排查

异常根因

异常由两个连锁问题共同触发,核心是类型不匹配:

  • 首先是Jackson反序列化的自动类型推断问题:你代码中实例化的ObjectMapper没有配置强制类型规则,当JSON字段值为纯数字格式的字符串(如"13"、"15")时,如果CommonCodeDTO类中code字段未明确约束类型、或未加反序列化注解,Jackson会自动将这类值识别为Integer类型;而"X1"这类包含非数字字符的值无法转为数值,会被正常识别为String类型。
  • 其次是Oracle对UNION结果集的类型校验规则:MyBatis的foreach拼接多段SELECT通过UNION合并为虚拟表时,要求所有SELECT分支同位置的字段类型完全一致。第一个分支传入的"X1"是VARCHAR2类型,后续分支传入的13、15是NUMBER类型,Oracle解析时直接抛出类型不匹配错误,导致纯数字编码的数据无法入库。

补充:如果你的CommonCodeDTO中code已经定义为String类型,那问题出在MyBatis的自动类型推断——未显式指定jdbcType时,MyBatis会根据传入值的实际类型匹配JDBC类型,部分Oracle驱动版本会对纯数字字符串做特殊类型处理,同样会触发UNION分支类型不一致问题。

修复方案

按以下顺序调整即可解决问题:

  1. 固定JSON反序列化的类型规则
    方法一(全局配置):修改ObjectMapper实例配置,强制文本类型字段就算值为纯数字,也按String类型反序列化:
ObjectMapper obj = new ObjectMapper();
// 对文本类型字段,整数格式输入强制转为字符串
obj.coercionConfigFor(LogicalType.Textual)
        .setCoercion(CoercionInputShape.Integer, CoercionAction.AsString);

方法二(字段级配置,更稳妥):在CommonCodeDTO类的code字段上加注解,强制按字符串解析:

@JsonFormat(shape = JsonFormat.Shape.STRING)
private String code;
  1. 显式指定MyBatis参数的JDBC类型
    将XML中#{item.code}修改为#{item.code, jdbcType=VARCHAR},强制MyBatis按字符串类型传参,从根源上避免JDBC层的类型自动推断,保证UNION所有分支的字段类型统一。
  2. (可选修复)修正Mapper参数绑定
    给Mapper接口的方法参数添加@Param注解,避免MyBatis默认参数解析规则找不到集合参数:
void innoMergeIntoCommonCodeGrade(@Param("commonCodeDTO") CommonCodeDTO[] commonCodeDTO);
  1. (可选优化)将SQL中拼接用的UNION改为UNION ALL,你的虚拟表数据本身不存在重复值,UNION ALL不需要做去重排序,执行效率更高,也能减少不必要的类型校验开销。

内容的提问来源于stack exchange,提问作者joskil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:48:45