mybatis中Error attempting to get column ‘xx‘ from result set处理方案汇总

本文汇总了在使用Mybatis时遇到'Error attempting to get column'异常的常见原因,包括字段名与数据库列名不一致、缺少无参构造或get/set方法,以及Druid对LocalDateTime处理的问题。针对Druid版本引发的异常,解决方案是升级Druid版本或更换数据库连接源。文中通过一个按日期查询课程记录的例子,展示了异常定位和解决的过程。
摘要由CSDN通过智能技术生成

常见的原因汇总
    1.封装集合中字段名与数据库列名不一致,检查是否一致以及是否有该字段;
    2.使用lombok或是其他操作导致没有无参构造或是无get/set;
    3.使用Druid,因为版本问题导致对于时间类型LocalDateTime.class处理异常;此种处理方案:不使用Druid或是使用其他数据库连接源进行替换或是Druid版本升级.
    先说一下此异常的出处:
BaseTypeHandler.java中getResult

  public T getResult(ResultSet rs, String columnName) throws SQLException {
    try {
      // 结果集中对数据库字段与实体类属性进行映射处理
      return getNullableResult(rs, columnName);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e, e);
    }
  }

    此异常之前还会有异常,也就是说该异常会有多种原因导致,也就对应了该异常出现的解决方案会有多种.这里说一下第三种异常处理方案的处理定位处理过程.
问题场景描述
    按照日期查询符合条件的课程记录信息,实体类中时间字段:startTime(格式为YYYY-MM-dd HH:mm:ss),数据库中字段start_time,字段类型dateTime.
    堆栈异常信息(篇幅原因删减部分堆栈信息):

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'start_time' from result set.  Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'start_time' from result set.  Cause: java.sql.SQLFeatureNotSupportedException
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'start_time' from result set.  Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'start_time' from result set.  Cause: java.sql.SQLFeatureNotSupportedException
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:87)
	... 73 more
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'start_time' from result set.  Cause: java.sql.SQLFeatureNotSupportedException
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
	... 99 more
Caused by: java.sql.SQLFeatureNotSupportedException
	at com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:1771)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:69)
	at com.sun.proxy.$Proxy190.getObject(Unknown Source)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:28)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
	... 101 more

    看堆栈信息,首先从最开始的位置开始看,很明显是LocalDateTimeTypeHandler.java中getNullableResult抛出的异常,最早出现的异常信息:java.sql.SQLFeatureNotSupportedException.
先看LocalDateTimeTypeHandler.java中getNullableResult

  public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getObject(columnName, LocalDateTime.class);
  }

    rs.getObject有很多中实现方式,由于使用的是Druid数据库连接源(最初使用的版本是1.0.28),所以直接定位到DruidPooledResultSet.java中getObject:

 public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
        throw new SQLFeatureNotSupportedException();
    }

    按照druid1.0.28翻看源码发现对于
关于日期类型处理说明LocalDateTime.class是不支持的,直接抛出SQLFeatureNotSupportedException.修改pom.xml中Druid版本,升级到1.2.1,然后看一下该版本的实现:

  public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
        try {
            return this.rs.getObject(columnLabel, type);
        } catch (Throwable var4) {
            throw this.checkException(var4);
        }
    }

说明高版本对LocalDateTime.class处理是支持的,重新测试之后正常!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卖柴火的小伙子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值