Mybatis Invalid bound statement

2022-04-10  本文已影响0人  MinXie

前两天在项目中遇到个很神奇的问题,想着周末有空的时候给解一下

问题的现象

在IDEA中执行main方法能正常跑通程序</br>
但是打包后,执行jar包会报错,错误信息如下:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

是在调用Mapper方法的时候抛出的异常


image.png

大胆猜测,小心求证

此时心中隐隐有答案,猜测大概率是数据源有问题,为了求证心中所想

我在报错的地方打了个断点,在两种不同的场景下分别进行调试

main调试

查看Mapper对应的数据源信息


image.png

jar包调试

使用调试模式执行jar包,打开命令行执行下面命令

java -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=y  -jar main.jar

在IDEA中配置端口号

image.png image.png
经过对比发现,Mapper注入的数据源果真是不一样的!

为什么会不一样呢???

代码都是一样的,配置也一样的,为啥打完jar后执行 注入的数据源就不同!

这时会怀疑是不是打包有问题,然后又解压了jar包去看,发现Mapper文件,数据源配置也都在,那大概可以排除是打包的问题了。

这条路走不通,那就换个思路去查一波

现在是可以定位到Mapper注入的数据源是异常的,那就查一下Mapper在注入这个数据源的时候发生了啥

那么Mapper是什么时候被Spring扫描的呢?

看一下spring-mybatis.xml配置文件发现配置了一个bean MapperScannerConfigurer

这个bean注入了扫描的mapper包位置和注入的数据源信息

image.png image.png

MapperScannerConfigurer类说明会从basePackage包开始递归实例化Mapper接口

好,那就先断个点在注入Mapper包(basePackage)的地方,debug看看,

image.png

观察一下前面执行的栈


image.png

好了,到了这,真相快大白了,前面的时候我们已经知道Mapper是注入了别的数据源,而项目中的数据源也比较多,那就有可能是别的配置文件里也扫描了该Mapper

然后谁先搜索到该Mapper就会注入该类型的数据源

果不其然,翻了别的配置文件一看,有个basePackage使用了通配符匹配,把该Mapper也扫描了进去!!!


image.png

为了验证是不是这个原因,我把该basePackage改了一下,不要扫描到该Mapper,打包执行,程序跑通了!没想到没想到。

再深入挖一下

问题出现的前提条件

那接着来看看spring扫描配置文件在不同场景下的做法

通过debug后定位到方法org.springframework.core.io.support.PathMatchingResourcePatternResolver#findPathMatchingResources

该方法会返回一个Resource数组,表示扫描的配置文件顺序

image.png

很正常的通过迭代器获取文件

image.png

这里的方法调用链会比较深,最后定位到方法
org.springframework.core.io.support.PathMatchingResourcePatternResolver#doRetrieveMatchingFiles
需要注意的是这里调用了Arrays.sort对文件进行了排序

image.png
image.png

所以才会有这么戏剧性的bug出现

上一篇 下一篇

猜你喜欢

热点阅读