当前使用版本(必填,否则不予处理)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
该问题是如何引起的?(确定最新版也有问题再提!!!)
- 确认为最新版
- sqlite 数据库(也是最新的
3.36.0.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异常.- 参考解决办法:可判断数据库类型,来决定这里调用
rs.getObject(columnName, this.propertyType);还是rs.getObject(columnName);,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