Spring Boot 启动时报 NumberFormatException: YES,最重要的不是异常栈有多长,而是 YES 在什么阶段被当成数字读取。这次故障发生在分片数据源加载表元数据时,不是在业务 INSERT 执行时。

当时的依赖组合

Spring Boot            2.1.4
Sharding-JDBC          4.0.0-RC3
mysql-connector-java   8.0.15

创建 shardingDataSource 失败,外层连带出现 Mapper、SqlSessionFactory 和 Controller 的依赖创建异常。这些是初始化失败向外传播的结果,不应逐个改业务 Bean。

从最内层向外读

下面保留原日志中足够定位的调用顺序,省略重复的 Spring 依赖创建栈:

NumberFormatException: For input string: "YES"
  Double.parseDouble
  MysqlTextValueDecoder.decodeDouble
  StringConverter.createFromBytes
  ResultSetImpl.getBoolean
  DelegatingResultSet.getBoolean
  TableMetaDataLoader.getColumnMetaDataList
  TableMetaDataLoader.createTableMetaData
  TableMetaDataInitializer.load
  SpringBootConfiguration.shardingDataSource

这里可以确认:布尔读取经过驱动转换时,进入了数字解析路径,输入恰好是 YES;再向上是 Sharding-JDBC 表元数据加载。仅凭这个栈还不足以确认具体列、驱动选项及上游修复提交,不应编造一个已锁定的 JDBC 字段原因。

当时只调整了候选版本

查到相近问题后,我把 Sharding-JDBC 从 4.0.0-RC3 改成 4.0.0-RC2,当时应用能够启动。这个结果说明依赖组合值得检查,但不是“8.0.15 永远不能搭配 RC3”的普遍证明。

RC2 是 2019 年的历史绕过,不是当前生产选型建议。启动成功也还不代表查询、路由和主键生成都通过。

遇到同类问题怎样收窄

先记录实际解析出来的依赖,而非只看 pom 中一个版本号。Maven 可用下面的只读命令查看相关传递依赖:

mvn dependency:tree -Dincludes=org.apache.shardingsphere:*,mysql:mysql-connector-java,org.apache.commons:commons-dbcp2

再固定服务端版本、表结构、连接参数及其他依赖,在隔离环境逐项比较;同一时间改驱动和中间件,会失去判断依据。若对照版本说明或源码,应使用准确 tag,不能拿新版本实现反推旧候选版一定有相同逻辑。

这次记录的可复用方法是:找出最内层转换失败,再分清框架初始化与业务调用。不要看到最外层 Mapper 创建失败,就先改 SQL 或数据库字段。