一、场景
1、项目使用ShardingJDBC操作数据库
2、查询SQL执行报错,但将sql复制到navicat中执行,是正常的
二、报错信息
nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
### The error may exist in file [/home/xxx/cloud/tomcat8-ccs-cloud/webapps/multi_channel_cloud_ccs/WEB-INF/classes/mappings/WorkTimeDao.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT recID, workType, workMode, weekIndex, defineDate, startDate, endDate, respondCode, type, vdnId FROM t_mb_itrWorkOverTime WHERE vdnId = '1' ORDER BY workType DESC
### Cause: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
三、排查
刚开始看到报错信息:java.lang.String cannot be cast to java.lang.Integer
1、以为是实体类属性类型与表字段没有对应上,随即对实体类属性类型调整,但依旧报错
2、将SQL映射类型更改为JSONObject【JSONObject是可以自动转换Integer与String的,应该可以解决问题】,依旧报错
3、连JSONObject都无法解决问题,将SQL查询字段写死:SELECT 1 AS vdnId FROM xxx,依旧报错
4、写死查询字段都不行,怀疑SQL语句是不是没有执行。
在SQL上随便添加符号,使SQL根本不成立。执行后依旧报错【懵,不成立的SQL也报错?这时想到,该项目使用的是SharDingJDBC,可能与JDBC有所区别,又看到报错信息:The error occurred while setting parameters,想到:如果不是查询字段的问题,那应该是条件字段的问题】
5、查看条件字段,发现表中对应的字段与实体类中对应的字段,属性类型是一样的,都是Integer类型。这时看到执行该SQL的方法,传递的参数类型是String,正好与报错信息一致。将方法参数类型改为Integer,问题得到解决
注:如果是JBDC链接,参数类型Integer与String是不会有冲突的,可以正常执行
四、原因
1、SQL查询WHERE中字段的字段类型没有对应上,表中的字段类型是Integer,查询时使用的是String
五、解决
更改执行该SQL的方法传递参数的参数类型,与数据库表中对应字段的类型一致