升级mybatis遇到的坑(NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare)
阅读原文时间:2021年04月20日阅读:1

今天要把项目中公司的框架版本升级到最新版,框架里mybatis版本升级到3.4.0.mod:1.5.5
执行命令查看mybatis的版本:mvn dependency:tree | grep mybatis

[2018-08-30 14:58:19][1535612299917_Eg2a] [ERROR] [http-nio-10095-exec-5] [com.souche.optimus.core.controller.JsonController:226]-- org.apache.ibatis.exceptions.PersistenceException:
### Error opening session.  Cause: org.apache.ibatis.plugin.PluginException: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
### Cause: org.apache.ibatis.plugin.PluginException: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
org.apache.ibatis.exceptions.PersistenceException:
### Error opening session.  Cause: org.apache.ibatis.plugin.PluginException: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
### Cause: org.apache.ibatis.plugin.PluginException: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:100)
    at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:57)
    at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:102)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:429)
    at com.sun.proxy.$Proxy28.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:231)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:139)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:76)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
    at com.sun.proxy.$Proxy38.selectByShopTypeAndBusinessType(Unknown Source)
    at com.souche.pandorabox.service.econtract.impl.EContractTemplateKeyServiceImpl.getEContractTemplateKeyBeanList(EContractTemplateKeyServiceImpl.java:38)
    at com.alibaba.dubbo.common.bytecode.Wrapper11.invokeMethod(Wrapper11.java)
    at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)
    at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)
    at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:63)
    at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:65)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:64)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.TokenFilter.invoke(TokenFilter.java:49)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.SoucheTraceFilter.invoke(SoucheTraceFilter.java:40)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:60)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:132)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
    at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:108)
    at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:86)
    at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:172)
    at com.alibaba.dubbo.remoting.rpc.http.codec.HttpRequestConvertHandler.received(HttpRequestConvertHandler.java:149)
    at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
    at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ibatis.plugin.PluginException: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
    at org.apache.ibatis.plugin.Plugin.getSignatureMap(Plugin.java:87)
    at org.apache.ibatis.plugin.Plugin.wrap(Plugin.java:44)
    at com.souche.optimus.mybatis.interceptor.MyBatisInterceptor.plugin(MyBatisInterceptor.java:63)
    at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:31)
    at org.apache.ibatis.session.Configuration.newExecutor(Configuration.java:586)
    at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:96)
    ... 43 more
Caused by: java.lang.NoSuchMethodException: org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)
    at java.lang.Class.getMethod(Class.java:1786)
    at org.apache.ibatis.plugin.Plugin.getSignatureMap(Plugin.java:84)
    ... 48 more

在mybatis的github上看到了这个问题:
https://github.com/mybatis/mybatis-3/issues/645

@Intercepts({@Signature(
    method = "prepare",
    type = StatementHandler.class,
    args = {Connection.class}
)})

作者在prepare这个方法的基础上增加了一个参数,而不是重载,所以根据原来的方法签名是找不到这个方法了,所以报错。作者也承认了这个问题:
全局更改一下方法的入参即可,一般拦截器都是配在mybatis的配置文件:mybatis-config.xml

<plugins>
     <plugin interceptor="XXX" >
         ...
     </plugin>
</plugins>

如果要注释掉上面的配置,记得要全部注释,不能只注释<plugin></plugin>的,<plugins></plugins>内起码要有一个子元素,不然会报下面的错误:

<!--<plugins>-->
    <!--<plugin interceptor="XXX" >-->
       ...
    <!--</plugin>-->
<!--</plugins>-->

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataFixAction': Unsatisfied dependency expressed through field 'dataMigrationService': Error creating bean with name 'dataMigrationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EContractParamExtendDao' defined in URL [jar:file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/lib/pandorabox-dao-1.0.2-SNAPSHOT.jar!/com/souche/pandorabox/dao/EContractParamExtendDao.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/classes/application-optimus-datasource.xml]: Invocation of init method failed; nested exception is org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 15; 元素类型为 "plugins" 的内容不完整, 它必须匹配 "(plugin)+"。; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataMigrationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EContractParamExtendDao' defined in URL [jar:file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/lib/pandorabox-dao-1.0.2-SNAPSHOT.jar!/com/souche/pandorabox/dao/EContractParamExtendDao.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/classes/application-optimus-datasource.xml]: Invocation of init method failed; nested exception is org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 15; 元素类型为 "plugins" 的内容不完整, 它必须匹配 "(plugin)+"。
[2018-08-30 20:17:35] [1535631451616_W6FT] [INFO ] [localhost-startStop-1] [com.alibaba.druid.pool.DruidDataSource:1823]-- {dataSource-1} closed
[2018-08-30 20:17:35] [1535631451616_W6FT] [ERROR] [localhost-startStop-1] [org.springframework.web.context.ContextLoader:351]-- Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataFixAction': Unsatisfied dependency expressed through field 'dataMigrationService': Error creating bean with name 'dataMigrationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EContractParamExtendDao' defined in URL [jar:file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/lib/pandorabox-dao-1.0.2-SNAPSHOT.jar!/com/souche/pandorabox/dao/EContractParamExtendDao.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/classes/application-optimus-datasource.xml]: Invocation of init method failed; nested exception is org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 15; 元素类型为 "plugins" 的内容不完整, 它必须匹配 "(plugin)+"。; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataMigrationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EContractParamExtendDao' defined in URL [jar:file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/lib/pandorabox-dao-1.0.2-SNAPSHOT.jar!/com/souche/pandorabox/dao/EContractParamExtendDao.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/classes/application-optimus-datasource.xml]: Invocation of init method failed; nested exception is org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 15; 元素类型为 "plugins" 的内容不完整, 它必须匹配 "(plugin)+"。
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4853)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataMigrationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EContractParamExtendDao' defined in URL [jar:file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/lib/pandorabox-dao-1.0.2-SNAPSHOT.jar!/com/souche/pandorabox/dao/EContractParamExtendDao.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [file:/home/souche/projects/pandorabox/.base/webapps/pandorabox.war/WEB-INF/classes/application-optimus-datasource.xml]: Invocation of init method failed; nested exception is org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 15; 元素类型为 "plugins" 的内容不完整, 它必须匹配 "(plugin)+"。
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)
    ... 24 common frames omitted