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

《org.apache.ibatis.type.TypeException》 错误堆栈

分析

  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方法看看。

《org.apache.ibatis.type.TypeException》 setParameter方法

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

《org.apache.ibatis.type.TypeException》 setNonNullParameter方法

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

《org.apache.ibatis.type.TypeException》 value是Integer类型

总结

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

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

    原文作者:猴猴猪027
    原文地址: https://www.jianshu.com/p/f9d0645cb082
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞