0
点赞
收藏
分享

微信扫一扫

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“


前言

这是最近 同事碰到的一个问题

感觉 有一些 奇怪, 然后 溜了一下 整个流程, 这里 记录一下

这是一个 mybatis-plus 组合上 mybatis-plus-join 出现的一个问题, 而且 还有一个需要的因素 就是 mybatis-plus-join 需要在 1.2.2 以及以下

 

 

测试用例

pom.xml 

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join</artifactId>
            <version>1.2.2</version>
        </dependency>

 

UserService 

@Service
public class UserService extends ServiceImpl<UserMapper, User> {

}

 

MyBatisConfig 

@Bean
    @Order(2)
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        return new MybatisPlusInterceptor();
    }

//    @Bean("com.github.yulichang.interceptor.MPJInterceptor")
//    @Order(-2)
//    public MPJInterceptor mpjInterceptor() {
//        return new MPJInterceptor();
//    }

 

MyCommandLIneRunner

/**
 * MyCommandLIneRunner
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2022-06-19 10:43
 */
@Configuration
public class MyCommandLIneRunner implements CommandLineRunner {

    @Resource
    private UserService userService;

    @Override
    public void run(String... args) throws Exception {
        int x = 0;
        User byId = userService.getById("ff8080817c07f871017c07f87adb0000");
        List<User> all = userService.list();
    }

}

 

然后 错误日志如下 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-06-19 12:09:45.488 [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:793)
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:774)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)
	at com.hx.boot.HelloSpringBootApplication.main(HelloSpringBootApplication.java:14)
Caused by: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'paramType_Gr8re1Ee' not found. Available parameters are [ew, param1]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
	at com.sun.proxy.$Proxy83.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77)
	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.$Proxy84.selectList(Unknown Source)
	at com.baomidou.mybatisplus.extension.service.IService.list(IService.java:370)
	at com.baomidou.mybatisplus.extension.service.IService.list(IService.java:379)
	at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685)
	at com.hx.boot.service.UserService$$EnhancerBySpringCGLIB$$9fd70305.list(<generated>)
	at com.hx.boot.config.MyCommandLIneRunner.run(MyCommandLIneRunner.java:28)
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:790)
	... 5 common frames omitted
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'paramType_Gr8re1Ee' not found. Available parameters are [ew, param1]
	at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:212)
	at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:120)
	at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:3341)
	at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:121)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:586)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:550)
	at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
	at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
	at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.lambda$apply$0(MixedSqlNode.java:32)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:32)
	at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:39)
	at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:305)
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:69)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
	at com.sun.proxy.$Proxy95.query(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
	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:427)
	... 20 common frames omitted

 

 

问题的调试

case1, 可以看到的是 来解析 sqlSource 中的 sqlNode 出现问题, 第四个 ifNode, 中参数 "paramType_Gr8re1Ee" 在参数的上下文中不存在  

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_apache_02

 

case2, 我们来看一下 没有 导入 mybatis-plus-join 的依赖的情况下 的查询情况, 因为没有导入 mybatis-plus-join 的情况下 执行是没有问题的 

可以看到的是 少了几个 Node, 没有我们上面的包含 "paramType_Gr8re1Ee" 的那个 IfNode 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_mybatis-plus_03

 

case3, 我们来看一下 项目完全 的查询情况, 因为在 applicationContext 完整加载了之后, 执行是没有问题的 

可以看到的是 这里有完整的 sqlSource 的 sqlNode 有完整的 12 个节点  

然后 参数中补充了一个参数 "paramType_Gr8re1Ee", 即为这里 需要的参数, 因此 没有报错 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_java_04

 

上面的两个参照会映射出一些问题 

1. 根据  case1 和 case2 的对比, 可以发现的是 mbatis-plus-join 对于查询 sql 的处理增加了一些 辅助的语句, 包含了这里出现问题的 "paramType_Gr8re1Ee"参数相关 

2. 根据 case1 和 case3 对比, applicationContext 完全加载之后, 查询的时候会在 参数中增加这个 "paramType_Gr8re1Ee"?, 当然  如果你够仔细的话 你可以从 case1 和 case3 的图中发现一些问题, 差异, 这些细节差异 造成了 这个问题 

3. "paramType_Gr8re1Ee" 的 sql 语句是从哪里来的?, 然后 参数"paramType_Gr8re1Ee"是从哪里填充的?

我们从 后面 来剖析这个问题的时候, 会解释出来 以上这些问题 

 

 

哪里增加的 "paramType_Gr8re1Ee" 这一系列语句?

MPJInjector 注入各个预制方法的时候, 一部分方法 的 tableName 是有更新 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_apache_05

 

这个 tableName 的实现来自于 TableAlias 的接口, 他有如下实现, 因此 如下 预制方法 均会出现这个问题 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_java_06

 

mybatis-plus-join 的 selectList 的实现大致如下, 使用的 SqlInjector 是 MPJSqlInector

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_mybatis-plus_07

 

如果是仅仅只有 mybatis-plus, selectList 的实现大致如下, 使用的 SqlInjector 是 DefaultSqlInector

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_mpj_08

 

 

applicationContext 初始化好了之后 哪里增加的参数 "paramType_Gr8re1Ee" ?

这个参数 "paramType_Gr8re1Ee" 的添加是在 MPJInterceptor 中添加 

另外注意 "当然  如果你够仔细的话 你可以从 case1 和 case3 的图中发现一些问题, 差异, 这些细节差异 造成了 这个问题", 注意 看这里的堆栈信息 

出现问题的堆栈信息, 是 MybatisPlusInterceptor, 而 正常的堆栈信息是 MPJInterceptor -> MybatisPlusInterceptor 

而参数 "paramType_Gr8re1Ee" 是 MPJInterceptor 添加进去的, 相当于使用的是 "MPJInterceptor" 生成的 sql, 但是 却没有使用 MPJInterceptor 来包装参数列表, 导致缺少了参数 "paramType_Gr8re1Ee" 

这里会 引申出关键的问题, 这个 interceptor列表 的执行到底是怎么回事 为什么 是在变化? 变化的规则到底是什么? 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_apache_09

 

 

这个 interceptor列表 的执行到底是怎么回事 为什么 是在变化? 变化的规则到底是什么?  

看正常情况下 DefaultSession 中的 executor, 外层 interceptor 是 MPJInterceptor, 内层 interceptor 是 MybatisDefaultInterceptor, 再内层是 具体的 executor 是一个 CachingExecutor 委托了一个 SImpleExecutor 来具体做事情 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring_10

 

出现问题的情况下 

看正常情况下 DefaultSession 中的 executor, 外层 interceptor 是 MybatisDefaultInterceptor, 内层 interceptor 是 MPJInterceptor, 再内层是 具体的 executor 是一个 CachingExecutor 委托了一个 SImpleExecutor 来具体做事情 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring_11

 

我们这里来探究一下 这个流程

session 的创建流程, 以及相关影响因素, 这里 executor 受到了 interceptorChain 的影响 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_java_12

 

interceptorChain 来自于 sessionFactory, sessionFactory 的 interceptor 来自于 sessionFactoryBean 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring_13

 

sessionFactoryBean 来自于 MybatisPlusAutoConfiguration 中创建的 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring_14

 

MybatisPlusAutoConfiguration 中的 interceptor 列表来自于 applicationContext 中查询到 Interceptor 列表, 然后 进行排序 

排序来自于 @Order 或者 @Priority 默认为 Integer.MAX_VALUE 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_spring_15

 

MPJInterceptor 在 mybatis-plus-join 1.2.2 中 @Order 为 -2147483648, MybatisPlusInterceptor 我这里随便配置的一个 2 

排序之后, MPJInterceptor 放在了 MybatisPlusInterceptor 之前 

然后创建了 代理之后, 形成的调用链就是 MybatisPlusInterceptor -> MPJInterceptor -> CachingExecutor -> SimpleExecutor, 也就是 出现问题的调用链 

 

 

在 applicationContext 加载完成之后 com.github.yulichang.config.InterceptorConfig 监听 applicationContext 加载完成的事件, 然后将 MPJInterceptor 放到 interceptor 列表的最后一个 

然后根据 openSessoin 创建出来的代理, 形成的调用链就是 MPJInterceptor -> MybatisPlusInterceptor -> CachingExecutor -> SimpleExecutor 

这个就是 applicationContext 加载完成之后, 正常调用 selectList 的情况 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_java_16

 

 

回溯一下这几个问题?

1. 根据  case1 和 case2 的对比, 可以发现的是 mbatis-plus-join 对于查询 sql 的处理增加了一些 辅助的语句, 包含了这里出现问题的 "paramType_Gr8re1Ee"参数相关 

2. 根据 case1 和 case3 对比, applicationContext 完全加载之后, 查询的时候会在 参数中增加这个 "paramType_Gr8re1Ee"?, 当然  如果你够仔细的话 你可以从 case1 和 case3 的图中发现一些问题, 差异, 这些细节差异 造成了 这个问题 

3. "paramType_Gr8re1Ee" 的 sql 语句是从哪里来的?, 然后 参数"paramType_Gr8re1Ee"是从哪里填充的?

 

 

MPJInterceptor 是怎么创建的?

来自于 AutoImport  

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_java_17

 

扫描 mybatis-plus-join-1.2.2.jar!/META-INF/spring.factories 的时候, 注册了这个 ConfigraionClass 

jar:file:/Users/jerry/.m2/repository/org/springframework/boot/spring-boot/2.0.0.RELEASE/spring-boot-2.0.0.RELEASE.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/org/springframework/spring-beans/5.0.4.RELEASE/spring-beans-5.0.4.RELEASE.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/org/springframework/data/spring-data-jpa/2.0.5.RELEASE/spring-data-jpa-2.0.5.RELEASE.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/org/springframework/data/spring-data-commons/2.0.5.RELEASE/spring-data-commons-2.0.5.RELEASE.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/com/baomidou/mybatis-plus-boot-starter/3.5.2/mybatis-plus-boot-starter-3.5.2.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.0.0.RELEASE/spring-boot-autoconfigure-2.0.0.RELEASE.jar!/META-INF/spring.factories
jar:file:/Users/jerry/.m2/repository/com/github/yulichang/mybatis-plus-join/1.2.2/mybatis-plus-join-1.2.2.jar!/META-INF/spring.factories

 

后面向 applicationContext 中注册了这个 beanDefinition 

102 在 CommandLineRunner 中执行 IBaseService.list 报错 “Parameter ‘paramType_Gr8re1Ee‘ not found“_apache_18

 

 

 完 

 

 

 

举报
0 条评论