当前使用版本(必填,否则不予处理)

  <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.5.2</version>
  </dependency>

该问题是如何引起的?(确定最新版也有问题再提!!!)

  1. 确认为最新版
  2. sqlite 数据库(也是最新的 3.36.0.3
  3. com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler#com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String) 方法调用了 rs.getObject(columnName, this.propertyType);. 但 sqlite 数据库并没有实现此方法,所以会抛出 SQLFeatureNotSupportedException 异常.
  4. 参考解决办法:可判断数据库类型,来决定这里调用 rs.getObject(columnName, this.propertyType); 还是 rs.getObject(columnName);, sqlite 实现了后者. 所有此类方法应该都会有此问题。

MyBatis-Plus 3.5.2 版本枚举处理器在 sqlite 数据库下解析异常的问题

MyBatis-Plus 3.5.2 版本枚举处理器在 sqlite 数据库下解析异常的问题

重现步骤(如果有就写完整)

见上方文字描述和报错信息 (3.5.2 之前,可以通过配置 mybatis-plus.configuration.default-enum-type-handler 复制源码修改此处来解决问题,但升级 3.5.2 之后,引入了 CompositeEnumTypeHandler,那个配置成了缺省值,只有没标记 @EnumValue 注解且没有实现 IEnum 的才会调用,故现在问题无法解决了,所以提出 issue)

报错信息

Caused by: java.sql.SQLFeatureNotSupportedException: null
    at org.sqlite.jdbc4.JDBC4ResultSet.getObject(JDBC4ResultSet.java:343)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
    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.$Proxy118.getObject(Unknown Source)
    at com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler.getNullableResult(MybatisEnumTypeHandler.java:118)
    at com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler.getNullableResult(MybatisEnumTypeHandler.java:49)
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
    at com.baomidou.mybatisplus.core.handlers.CompositeEnumTypeHandler.getResult(CompositeEnumTypeHandler.java:62)
    at com.baomidou.mybatisplus.core.handlers.CompositeEnumTypeHandler.getResult(CompositeEnumTypeHandler.java:37)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:518)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:487)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:411)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:361)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:335)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:308)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:201)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
    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.plugin.Plugin.invoke(Plugin.java:64)
    at com.sun.proxy.$Proxy116.query(Unknown Source)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
    at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
    at com.sun.proxy.$Proxy115.query(Unknown Source)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
    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.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
    ... 61 common frames omitted

Comment From: huayanYu

欢迎PR

Comment From: uncarbon97

这里有自定义实现 LocalDateTimeTypeHandler 的 DEMO,你按自己需求修改后,试一下注册到 spring 里能不能实现 type handler

import cn.hutool.core.convert.Convert;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.LocalDateTimeTypeHandler;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.stereotype.Component;


@Component
@MappedTypes(LocalDateTime.class)
@MappedJdbcTypes(value = JdbcType.TIMESTAMP, includeNullJdbcType = true)
public class LocalDateTimeTypeHandlerInjector extends LocalDateTimeTypeHandler {

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return Convert.toLocalDateTime(rs.getObject(columnName));
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return Convert.toLocalDateTime(rs.getObject(columnIndex));
    }

    @Override
    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return Convert.toLocalDateTime(cs.getObject(columnIndex));
    }
}

Comment From: qmdx

UP 参考实现自己的 typeHandler