zoukankan      html  css  js  c++  java
  • 记一次mybatis bindingexception 问题排查

    看到的错误信息如出一辙都是这样的:Method threw 'org.apache.ibatis.binding.BindingException' exception.Invalid bound statement (not found): **.dao.**Dao.select

    1.考虑返回值类型是否不匹配,一顿修改,@Results 也使用到。 最终无果。

    2.开始各种百度,先申明本人使用的方式注解方式, 并非最常用的xml方式。 百度内容大都雷同,检查包名,类名,方法名 是否映射。无果。

    3.由于 mybatis 报的错误,不是很明确。 无奈只能debug 源码。

    4. 查看更为详细的异常日志

     1 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.sankuai.meituan.banma.thrift.activity.admin.dao.CouponPossessDao.selectUnusedPageNum
     2     at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:214) ~[mybatis-3.4.0.jar:3.4.0]
     3     at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:48) ~[mybatis-3.4.0.jar:3.4.0]
     4     at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59) ~[mybatis-3.4.0.jar:3.4.0]
     5     at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) ~[mybatis-3.4.0.jar:3.4.0]
     6     at com.sun.proxy.$Proxy96.selectUnusedPageNum(Unknown Source) ~[na:na]
     7     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
     8     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
     9     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
    10     at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
    11     at com.dianping.zebra.dao.AsyncMapperProxy.invoke(AsyncMapperProxy.java:64) ~[zebra-dao-0.2.4.jar:na]
    12     at com.sun.proxy.$Proxy96.selectUnusedPageNum(Unknown Source) ~[na:na]

    第二行是重点。点击查看代码。

     1  public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
     2             String statementName = mapperInterface.getName() + "." + method.getName();
     3             MappedStatement ms = null;
     4             if(configuration.hasStatement(statementName)) { //正常的逻辑都会进入该 if 逻辑,然后得到ms。 该方法未进入该逻辑。不到是该方法初始化时,就失败了。
     5                 ms = configuration.getMappedStatement(statementName);
     6             } else if(!mapperInterface.equals(method.getDeclaringClass())) {
     7                 String parentStatementName = method.getDeclaringClass().getName() + "." + method.getName();
     8                 if(configuration.hasStatement(parentStatementName)) {
     9                     ms = configuration.getMappedStatement(parentStatementName);
    10                 }
    11             }
    12 
    13             if(ms == null) {
    14                 if(method.getAnnotation(Flush.class) == null) {
    15                     throw new BindingException("Invalid bound statement (not found): " + statementName); //该行即为抛出的异常日志
    16                 }
    17 
    18                 this.name = null;
    19                 this.type = SqlCommandType.FLUSH;
    20             } else {
    21                 this.name = ms.getId();
    22                 this.type = ms.getSqlCommandType();
    23                 if(this.type == SqlCommandType.UNKNOWN) {
    24                     throw new BindingException("Unknown execution method for: " + this.name);
    25                 }
    26             }
    27 
    28         }

    下面开始追踪初始化的代码块。

     1 public class ZebraMapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
     2     private Class<T> mapperInterface;
     3     private boolean addToConfig = true;
     4 
     5     public ZebraMapperFactoryBean() {
     6     }
     7 
     8     public void setMapperInterface(Class<T> mapperInterface) {
     9         this.mapperInterface = mapperInterface;
    10     }
    11 
    12     public void setAddToConfig(boolean addToConfig) {
    13         this.addToConfig = addToConfig;
    14     }
    15 
    16     protected void checkDaoConfig() {
    17         super.checkDaoConfig();
    18         Assert.notNull(this.mapperInterface, "Property 'mapperInterface' is required");
    19         Configuration configuration = this.getSqlSession().getConfiguration();
    20         if(this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
    21             try {
    22                 configuration.addMapper(this.mapperInterface);//下面跟进该方法查询具体的报错行
    23             } catch (Throwable var6) {
    24                 this.logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", var6); // 初始化时,执行到这里其实已经报错了。但是没影响启动
    25                 throw new IllegalArgumentException(var6);
    26             } finally {
    27                 ErrorContext.instance().reset();
    28             }
    29         }
    30 
    31     }
    
    

    public class MapperAnnotationBuilder {

    private SqlSource getSqlSourceFromAnnotations(Method method, Class<?> parameterType, LanguageDriver languageDriver) {
    try {
    Class<? extends Annotation> sqlAnnotationType = this.getSqlAnnotationType(method);
    Class<? extends Annotation> sqlProviderAnnotationType = this.getSqlProviderAnnotationType(method);
    Annotation sqlProviderAnnotation;
    if(sqlAnnotationType != null) {
    if(sqlProviderAnnotationType != null) {
    throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName());
    } else {
    sqlProviderAnnotation = method.getAnnotation(sqlAnnotationType);
    String[] strings = (String[])((String[])sqlProviderAnnotation.getClass().getMethod("value", new Class[0]).invoke(sqlProviderAnnotation, new Object[0]));
    return this.buildSqlSourceFromStrings(strings, parameterType, languageDriver);
    }
    } else if(sqlProviderAnnotationType != null) {
    sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType);
    return new ProviderSqlSource(this.assistant.getConfiguration(), sqlProviderAnnotation);
    } else {
    return null;
    }
    } catch (Exception var8) {
    throw new BuilderException("Could not find value method on SQL annotation. Cause: " + var8, var8); //最初的报错的位置
    }
    }
    
    

    这里就可以找到具体的初始化失败的方法了。

    5.至此找到了,正确的解决方案。

    6.由此得出几个结论。1.mybatis 报警的确是很不明确。  2.出现问题,优先还是优先考虑排除法。一段代码一段代码检查。 

  • 相关阅读:
    腾信短信接口实例
    ajax
    jquery
    生命鸡汤
    sql中事物
    ajax,一般处理程序,登陆
    CSS选择器大全
    【JavaScript】轮播图
    【DOM练习】淘宝购物车
    【DOM练习】百度历史搜索栏
  • 原文地址:https://www.cnblogs.com/qunan/p/8330780.html
Copyright © 2011-2022 走看看