SpringBoot+myBatisPlus+sharding-jdbc数据源分页查询类型转换问题

在实际项目中涉及到多数据源和分表,所以采用了shardingsphere,为了简化代码,引入了mybatis plus

版本:

mybatis plus:3.3.2

springboot:2.1.5

shardingsphere : 4.0.0-RC2

错误信息

Caused by: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
### The error may exist in com/cxm/db/mapper/bi/CxmBiDemoDAO.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT  id,increased_stall_count  FROM cxm_bi_demo LIMIT ?,?
### Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
	at com.sun.proxy.$Proxy150.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForIPage(MybatisMapperMethod.java:134)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:96)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:96)
	at com.sun.proxy.$Proxy157.selectPage(Unknown Source)
	at com.cxm.service.CxmBaseServiceImpl.page(CxmBaseServiceImpl.java:292)
	at com.cxm.service.CxmBaseServiceImpl.page(CxmBaseServiceImpl.java:307)
	at com.cxm.service.CxmBaseServiceImpl$$FastClassBySpringCGLIB$$5d9c5448.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
	at com.cxm.service.impl.CxmBiDemoServiceImpl$$EnhancerBySpringCGLIB$$e0e43073.page(<generated>)
	at com.cxm.service.impl.CxmBiDailyIncreasedStatisticServiceImpl.queryIn(CxmBiDailyIncreasedStatisticServiceImpl.java:86)
	at com.cxm.service.impl.CxmBiDailyIncreasedStatisticServiceImpl$$FastClassBySpringCGLIB$$588bac5b.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
	at com.cxm.service.impl.CxmBiDailyIncreasedStatisticServiceImpl$$EnhancerBySpringCGLIB$$bbed46d4.queryIn(<generated>)
	at com.cxm.CxmRetailApplication.run(CxmRetailApplication.java:68)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813)
	... 5 common frames omitted
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
### The error may exist in com/cxm/db/mapper/bi/CxmBiDemoDAO.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT  id,increased_stall_count  FROM cxm_bi_demo LIMIT ?,?
### Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
	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:426)
	... 32 common frames omitted
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	at org.apache.shardingsphere.core.optimize.sharding.segment.select.pagination.Pagination.getValue(Pagination.java:60)
	at org.apache.shardingsphere.core.optimize.sharding.segment.select.pagination.Pagination.<init>(Pagination.java:54)
	at org.apache.shardingsphere.core.optimize.sharding.segment.select.pagination.engine.LimitPaginationEngine.createPagination(LimitPaginationEngine.java:40)
	at org.apache.shardingsphere.core.optimize.sharding.segment.select.pagination.engine.PaginationEngine.createPagination(PaginationEngine.java:50)
	at org.apache.shardingsphere.core.optimize.sharding.engnie.dml.ShardingSelectOptimizeEngine.optimize(ShardingSelectOptimizeEngine.java:63)
	at org.apache.shardingsphere.core.optimize.sharding.engnie.dml.ShardingSelectOptimizeEngine.optimize(ShardingSelectOptimizeEngine.java:47)
	at org.apache.shardingsphere.core.route.router.sharding.ParsingSQLRouter.route(ParsingSQLRouter.java:72)
	at org.apache.shardingsphere.core.route.PreparedStatementRoutingEngine.route(PreparedStatementRoutingEngine.java:66)
	at org.apache.shardingsphere.core.PreparedQueryShardingEngine.route(PreparedQueryShardingEngine.java:60)
	at org.apache.shardingsphere.core.BaseShardingEngine.executeRoute(BaseShardingEngine.java:86)
	at org.apache.shardingsphere.core.BaseShardingEngine.shard(BaseShardingEngine.java:70)
	at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.shard(ShardingPreparedStatement.java:224)
	at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.execute(ShardingPreparedStatement.java:170)
	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.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
	at com.sun.proxy.$Proxy227.execute(Unknown Source)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
	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:63)
	at com.sun.proxy.$Proxy226.query(Unknown Source)
	at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:67)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:163)
	at com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:90)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	... 38 common frames omitted

问题分析:

追踪日志,查看源码发现是由于shardingsphere的Pagination中有一个类型转换直接写死为int类型导致的,

因为分页参数里面穿的值是Long的类型,而下面这个方法直接强制转换为int,所以导致出错

private int getValue(final PaginationValueSegment paginationValueSegment, final List<Object> parameters) {
        return paginationValueSegment instanceof ParameterMarkerPaginationValueSegment
                ? (int) parameters.get(((ParameterMarkerPaginationValueSegment) paginationValueSegment).getParameterIndex())
                : ((NumberLiteralPaginationValueSegment) paginationValueSegment).getValue();
    }

因为mybatisplus的分页对象IPage里面的属性是long

扫描二维码关注公众号,回复: 13042616 查看本文章

解决方案:

1:自定义实现com.baomidou.mybatisplus.core.metadata.IPage;,
将 private long size;private long current; 修改为int 类型可以修复这个问题,但没有进行覆盖测试,不知道是否会引起其他问题

2:重新shardingsphere的Pagination

3:弃用shardingsphere-core,分库分表采用阿里云的组建,多数据源采用AbstractRoutingDataSource自定义注解实现

猜你喜欢

转载自blog.csdn.net/Crystalqy/article/details/107929937