org.apache.ibatis.type.TypeException

org.apache.ibatis.type.TypeException

问题

根据客户id查询客户信息,报出如下错误

org.apache.ibatis.type.TypeExceptionCould not set parameters for mapping: ParameterMapping{property='id', mode=IN, javaType=class java.lang.Long, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null 
. Cause: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
错误堆栈

分析

  public void setParameters(PreparedStatement ps) {
    ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    if (parameterMappings != null) {
      for (int i = 0; i < parameterMappings.size(); i++) {
        ParameterMapping parameterMapping = parameterMappings.get(i);
        if (parameterMapping.getMode() != ParameterMode.OUT) {
          Object value;
          String propertyName = parameterMapping.getProperty();
          if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
            value = boundSql.getAdditionalParameter(propertyName);
          } else if (parameterObject == null) {
            value = null;
          } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
            value = parameterObject;
          } else {
            MetaObject metaObject = configuration.newMetaObject(parameterObject);
            value = metaObject.getValue(propertyName);
          }
          TypeHandler typeHandler = parameterMapping.getTypeHandler();
          JdbcType jdbcType = parameterMapping.getJdbcType();
          if (value == null && jdbcType == null) {
            jdbcType = configuration.getJdbcTypeForNull();
          }
          try {
          //出错是在这一行,typeHandler是从parameterMapping取得,是LongTypeHandler
            typeHandler.setParameter(ps, i + 1, value, jdbcType);
          } catch (TypeException e) {
            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
          } catch (SQLException e) {
            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
          }
        }
      }
    }
  }

typeHandler是从parameterMapping中取的,是LongTypeHandler类型,我们今setParameter方法看看。

setParameter方法

方法的核心是setNonNullParameter,如图。该方法在BaseTypeHandler是抽象方法,方法实际在LongTypeHandler中,我们看看。

setNonNullParameter方法

方法的第三个参数是Long型,我们调用时传参是Integer类型,所以就发生了错误。

value是Integer类型

总结

setParameter方法实际调用的是哪一个TypeHandler是有ParamaterMapping决定的,ParameterMapping又是解析xml得到的,所以如果接口中的类型和xml中的类型不一致,调用方法就会发生类型转换错误。

后面会分析如果xml中不设置ParameterType会发生什么,是否也就有类似的错误出现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 出现无效字符、无效的列索引 这是因为sql语句最后多了一个分号,去掉就可以了
    yuditxj阅读 1,912评论 0 0
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,754评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,868评论 18 139
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,571评论 0 4
  • 最近,我在Linux Centos 6.6上安装了最新的ffmpeg,本教程会教新手用户如何安装ffmpeg和从源...
    hswwjp阅读 637评论 0 0