错误场景:
- 使用 mybatis-plus 的 getById()方法,返回结果竟然是多条记录。
- 参数已确定是主键id。
- 通过数据库可视化工具 执行sql 返回是一条记录。
通过可视化工具执行sql是一条记录,但是 通过 mybatis-plus 的getById() 方法确是多条记录。
错误日志:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
at com.sun.proxy.$Proxy153.selectOne(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:159)
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:90)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
at com.sun.proxy.$Proxy156.selectById(Unknown Source)
at com.baomidou.mybatisplus.extension.service.IService.getById(IService.java:199)
at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685)
at cn.com.chnsys.eleac4.sys_common.service.impl.ConfigRuleDetailServiceImpl$$EnhancerBySpringCGLIB$$4e131247.getById(<generated>)
at cn.com.chnsys.eleac4.rule.RuleApplicationTests.test3(RuleApplicationTests.java:91)
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.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:80)
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)
... 75 more
sql查询日志:
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@140fa482] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@2027818863 wrapping com.mysql.jdbc.JDBC4Connection@3b063aaf] will not be managed by Spring
==> Preparing: SELECT ID,ZONGTPZID AS configTotalId,ZONGTPZLX AS configTotalType,ZONGTPZMC AS configTotalName,XUNCXMC AS configRuleDetailName,ZHUCID AS registrId,JISGZ AS calRule,BEIYZFC8 AS ReservedString8,BEIYZFC7 AS ReservedString7,BEIYZFC6 AS ReservedString6,BEIYZFC5 AS ReservedString5,BEIYZFC4 AS ReservedString4,BEIYZFC3 AS ReservedString3,BEIYZFC2 AS ReservedString2,BEIYZFC1 AS ReservedString1,BEIYZT5 AS ReservedInt5,BEIYZT4 AS ReservedInt4,BEIYZT3 AS ReservedInt3,BEIYZT2 AS ReservedInt2,BEIYZT1 AS ReservedInt1 FROM eleac_guizpz WHERE ID=?
==> Parameters: 4(Integer)
<== Columns: ID, configTotalId, configTotalType, configTotalName, configRuleDetailName, registrId, calRule, ReservedString8, ReservedString7, ReservedString6, ReservedString5, ReservedString4, ReservedString3, ReservedString2, ReservedString1, ReservedInt5, ReservedInt4, ReservedInt3, ReservedInt2, ReservedInt1
<== Row: 4, 4, 4, 完整性, 完整性, 2, <<BLOB>>, null, null, null, null, null, null, null, null, null, null, null, null, null
<== Row: 4C56B386-8257-4991-A6BF-29D2EEFBF299, 1, 1, 及时性, 行政二审外部卷宗规则, 1, <<BLOB>>, null, null, null, null, null, null, null, null, null, null, null, null, null
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@140fa482]
错误分析
实体对象主键 id 数据类型是 String,数据库主键类型为 varcher。但是程序传递给 mybatis-plus的getById()方法 的参数类型却是Integer
在sql查询日志中可以看到:==> Parameters: 4(Integer)
sql的参数为Integer,与实体数据类型不同。与mybayis-plus底层原理有关,此处不进行分析。
错误解决:修改查询参数为string,
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@439047ef] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@2114163679 wrapping com.mysql.jdbc.JDBC4Connection@301b2259] will not be managed by Spring
==> Preparing: SELECT ID,ZONGTPZID AS configTotalId,ZONGTPZLX AS configTotalType,ZONGTPZMC AS configTotalName,XUNCXMC AS configRuleDetailName,ZHUCID AS registrId,JISGZ AS calRule,BEIYZFC8 AS ReservedString8,BEIYZFC7 AS ReservedString7,BEIYZFC6 AS ReservedString6,BEIYZFC5 AS ReservedString5,BEIYZFC4 AS ReservedString4,BEIYZFC3 AS ReservedString3,BEIYZFC2 AS ReservedString2,BEIYZFC1 AS ReservedString1,BEIYZT5 AS ReservedInt5,BEIYZT4 AS ReservedInt4,BEIYZT3 AS ReservedInt3,BEIYZT2 AS ReservedInt2,BEIYZT1 AS ReservedInt1 FROM eleac_guizpz WHERE ID=?
==> Parameters: 4(String)
<== Columns: ID, configTotalId, configTotalType, configTotalName, configRuleDetailName, registrId, calRule, ReservedString8, ReservedString7, ReservedString6, ReservedString5, ReservedString4, ReservedString3, ReservedString2, ReservedString1, ReservedInt5, ReservedInt4, ReservedInt3, ReservedInt2, ReservedInt1
<== Row: 4, 4, 4, 完整性, 完整性, 2, <<BLOB>>, null, null, null, null, null, null, null, null, null, null, null, null, null
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@439047ef]