[关闭]
@aloxc 2017-12-05T06:39:07.000000Z 字数 8291 阅读 824

mybatis配置sharding-jdbc的一个Cause: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0异常分析

mybatis shading-jdbc


这两天在重构mybatis一段代码的时候,想结合当当网的sharding-jdbc,出现了一个异常,异常堆栈如下

  1. org.apache.ibatis.exceptions.PersistenceException:
  2. ### Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
  3. ### The error may exist in class path resource [mapper/notice/notice-setting-mapper.xml]
  4. ### The error may involve xxpackage.bbs.notice.dao.INoticeSettingDao.getSetting
  5. ### The error occurred while handling results
  6. ### SQL: SELECT * FROM bbs_notice_setting WHERE user_id = ? LIMIT 1
  7. ### Cause: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
  8. at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
  9. at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
  10. at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
  11. at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
  12. at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)
  13. at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
  14. at com.sun.proxy.$Proxy59.getSetting(Unknown Source)
  15. at xxpackage.bbs.notice.dao.NoticeSettingDao.getSetting(NoticeSettingDao.java:34)
  16. at xxpackage.bbs.notice.dao.NoticeSettingDao$$FastClassBySpringCGLIB$$5e52de10.invoke(<generated>)
  17. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  18. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:700)
  19. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
  20. at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
  21. at xxpackage.lib.dynamicDataSource.DynamicDataSourceAspect.doAround(DynamicDataSourceAspect.java:56)
  22. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  23. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  24. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  25. at java.lang.reflect.Method.invoke(Method.java:498)
  26. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
  27. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
  28. at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
  29. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
  30. at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
  31. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
  32. at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:633)
  33. at xxpackage.bbs.notice.dao.NoticeSettingDao$$EnhancerBySpringCGLIB$$f8f6ae68.getSetting(<generated>)
  34. at xxpackage.bbs.notice.dao.NoticeSettingDaoTest.getSetting(NoticeSettingDaoTest.java:26)
  35. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  36. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  37. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  38. at java.lang.reflect.Method.invoke(Method.java:498)
  39. at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  40. at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  41. at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  42. at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  43. at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
  44. at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
  45. at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
  46. at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
  47. at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
  48. at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  49. at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  50. at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  51. at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  52. at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  53. at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
  54. at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
  55. at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  56. at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
  57. at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  58. at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
  59. at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
  60. at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
  61. at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  62. Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
  63. at java.util.ArrayList.rangeCheck(ArrayList.java:653)
  64. at java.util.ArrayList.get(ArrayList.java:429)
  65. at com.dangdang.ddframe.rdb.sharding.merger.MergeEngine.<init>(MergeEngine.java:56)
  66. at com.dangdang.ddframe.rdb.sharding.jdbc.core.statement.ShardingStatement.getResultSet(ShardingStatement.java:252)
  67. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  68. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  69. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  70. at java.lang.reflect.Method.invoke(Method.java:498)
  71. at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:69)
  72. at com.sun.proxy.$Proxy62.getResultSet(Unknown Source)
  73. at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getFirstResultSet(DefaultResultSetHandler.java:226)
  74. at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:176)
  75. at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
  76. at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
  77. at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
  78. at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
  79. at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
  80. at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
  81. at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
  82. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  83. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  84. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  85. at java.lang.reflect.Method.invoke(Method.java:498)
  86. at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)
  87. at xxpackage.lib.mybatis.SqlLogIntercept.intercept(SqlLogIntercept.java:65)
  88. at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
  89. at com.sun.proxy.$Proxy58.query(Unknown Source)
  90. at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
  91. ... 52 more

其中spring-mybatis的配置文件中关于sharding-jdbc的分表策略配置如下

  1. <rdb:strategy id="noticeSettingSharding" sharding-columns="user_id" algorithm-expression="bbs_notice_setting_${user_id.longValue() / 10000000}"/>
  2. ```
  3. user_id在数据库中是int类型,javabean中也是int类型,这段配置${user_id.longValue() / 10000000}执行的是groovy代码,其意思是分表策略使用user_id整除来分表,那这段执行后的long值,我猜问题就出现在这。
  4. 为了验证我的猜想,把上面的代码调整下
  5. <div class="md-section-divider"></div>
  6. ```xml
  7. <rdb:strategy id="noticeSettingSharding" sharding-columns="user_id" algorithm-expression="bbs_notice_setting_${0}"/>

调整后再次执行测试代码,这次没有任何异常,正确的执行了,那确定就是这个配置错误引起的,修改下代码

  1. <rdb:strategy id="noticeSettingSharding" sharding-columns="user_id"
  2. algorithm-expression="bbs_notice_setting_${(user_id.longValue()/10000000).toInteger()}"/>

调整后运行测试逻辑代码无误,修改完毕!
x

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注