数据库最后一个字段Null导致mybatis抛出异常ArrayIndexOutOfBoundsException

探讨了在使用Springboot结合MyBatis和MySQL时,因查询结果中最后一个字段为null而导致的ArrayIndexOutOfBoundsException异常。分析了mysql-connector-java驱动的问题所在,并提供了两种解决方案:升级驱动或代码层面控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库最后一个字段Null导致mybatis抛出异常ArrayIndexOutOfBoundsException

mybatis抛出异常ArrayIndexOutOfBoundsException

项目框架

Spring boot1.5.9 + mybatis3 + mysql-conector-java 6.0.6

出错原因

查询表返回的记录中最后一个字段值是null,mybatis组装pojo失败,会抛出ArrayIndexOutOfBoundsException异常。如果通过错误栈发现,实际是mysql驱动mysql-conector-java在BinaryBufferRow.getValue这个方法中最先抛出的。跟踪源码发现,在获取最后一个字段值时,由于是null值,错误的走了readInteger方法

  public <T> T getValue(int columnIndex, ValueFactory<T> vf)
  {
    findAndSeekToOffset(columnIndex);

    int type = this.metadata.getFields()[columnIndex].getMysqlTypeId();
    int length = MysqlaUtils.getBinaryEncodedLength(type);
    if (length == 0) //最后一个字段是Null,长度为0,走了if分支中。
      length = (int)this.rowFromServer.readInteger(NativeProtocol.IntegerDataType.INT_LENENC);
    else if (length == -1) {
      throw ExceptionFactory.createException(Messages.getString("MysqlIO.97", new Object[] { Integer.valueOf(type), Integer.valueOf(columnIndex + 1), Integer.valueOf(this.metadata.getFields().length) }), this.exceptionInterceptor);
    }

    return getValueFromBytes(columnIndex, this.rowFromServer.getByteBuffer(), this.rowFromServer.getPosition(), length, vf);
  }

去maven库查了最新的驱动版本8(8.x版本),发现已修改这个问题:

    public <T> T getValue(int columnIndex, ValueFactory<T> vf) {
        this.findAndSeekToOffset(columnIndex);
        int type = this.metadata.getFields()[columnIndex].getMysqlTypeId();
        int length = NativeUtils.getBinaryEncodedLength(type);
        if(!this.getNull(columnIndex)) {   //主要是多了这行,预先判断了是否Null值,如果是,则走getValueFromBytes方法。
            if(length == 0) {
                length = (int)this.rowFromServer.readInteger(IntegerDataType.INT_LENENC);
            } else if(length == -1) {
                throw ExceptionFactory.createException(Messages.getString("MysqlIO.97", new Object[]{Integer.valueOf(type), Integer.valueOf(columnIndex + 1), Integer.valueOf(this.metadata.getFields().length)}), this.exceptionInterceptor);
            }
        }

        return this.getValueFromBytes(columnIndex, this.rowFromServer.getByteBuffer(), this.rowFromServer.getPosition(), length, vf);
    }

解决方法

  1. 升级mysql驱动,我之前是6.0.6,升到最新版本8.x.x
  2. 代码中人为控制最后一列记录不要为NULL。
    第一种简单快捷,一劳永逸。缺点是对项目的影响最大,可能有新的坑要踩。
    第二种改了不影响项目其它代码,缺点是改动量大,还有可能会漏改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值