I am kite, the public account “ancient time kite”, a not only technology public account, I have been in the app community for many years, mainly Java, Python, React also play 6 slash developer. The Spring Cloud series is complete, and you can check out the full series on my Github. You can also reply “PDF” in the public account to get the full PDF version of my elaborate tutorial.

Writing code for many years, I have always had a habit, as long as the function module to be done is not very complex, usually come up to write a lot of code, and wait for the function to complete, then start the service test, where there is a problem, and then change (to be honest, there are not many unit tests written). Instead of writing an interface or method and then testing it, the longest record is to write code for 4 or 5 days in a row and then pass the test in a handful, which feels like an extra bowl of rice.

Waterloo on code Road

However, just the other day, I felt like I had suffered a code failure. In fact, I had experienced this more than once. This time, LET me write it down so I don’t forget it.

The thing is, two days ago, we need to add a function to the project. The ORM of the project adopts MyBatis. Since the database table is added, the CORRESPONDING DAO layer and MyBatis mapping file (mapper.xml) should be generated. Because the business is not familiar with before, I just put each entity class and business class, the mapping file and enumeration class and so on are built up, and then wrote two simple interface ready to be debugged, so I ordered the start button, no problem, no error, project launched normally, looked so perfect.

MyBatis: invalid bound Statement (not found) MyBatis: invalid bound Statement (not found) MyBatis: invalid bound Statement (not found) Mapper.xml does not find the corresponding statement, or block of the SQL query you defined, when you called the DAO method.

There are several possible reasons for this exception:

  1. The namespace name of the XML file is inconsistent with the interface name
  2. The method in the interface class does not correspond to the Statement ID in the XML file
  3. There are Chinese annotations in the XML file
  4. Feel free to add a space or a blank line to the XML file and save it

This is fine if you use a tool to generate the XML automatically. If you create the XML manually, you may have inadvertently created the XML. For example, we copied the XML from another file, forgot to change the namespace, or the interface method name differs by one letter from the Statement ID, or the alphabetical order is different. This exception can be a pain in the neck, such as a one-letter difference, which is hard to detect, so it’s best to write the interface method name and copy it to XML.

Although I have not touched MyBatis for some time, as an old driver, I am not at all alarmed when I encounter this problem, because although it is an XML file automatically generated by the tool, I did add several statement blocks, and the ID was also typed by hand, and the error was also added manually, so, I guess it must be the wrong name, the wrong letter or the order is not the same, so I went in to check, but found nothing wrong, just to be safe, I went to the interface to copy the method name into THE XML, and then made sure that the namespace is ok, there is no Chinese comment. I added a blank line to the XML (though I never used this method to solve the problem) and restarted the project, but the exception did not go away.

Jump out in time, don’t get stuck

That was a little strange. I checked it again, and, yes, everything was fine. I couldn’t see what was wrong. ** When sure there is no problem, it is time to jump out, have to consider from other directions or a higher level, otherwise it is likely to be trapped inside. ** delimit the key point, this is many lessons summed up the rule. I was able to confirm that the interface method and statement that I was calling were all right, and that there was probably something else wrong with the XML file. I went to the target directory to check if there was anything wrong.

Sometimes the problem was strange, probably IDE related, so I cleaned it up with the MVN clean command and re-ran it, but the problem was still there.

Next, I tried deleting the XML and creating a new one, but the problem remained.

Jump out again, you are not this method has a problem, then I create a new method, write a simple SQL, the method name is also a simple point, see if there will be a problem, as a result, found the new world, this new method also reported this error. The result is that all the methods under this package name have this error, while the methods under other package names have no problem, because the XML files with different functions are placed under different packages, that is, under different paths.

MyBatis mapperLocations (MyBatis mapperLocations) is not working. MyBatis mapperLocations (MyBatis mapperLocations) is not working. MyBatis mapperLocations is not working. So I opened up the configuration file and looked at it,

mybatis:
  mapperLocations: com/xxx/aaa/mapper/*.xml,com/xxx/aaa/bbb/mapper/*.xml,com/xxx/aaa/ccc/mapper/*.xml
Copy the code

*. XML file. There is no git commit record in the configuration file. There is a problem with com/ XXX /aaa/ CCC /mapper/*.xml. So I tried the following methods:

  1. Put the package path in question first, invalid.
  2. Leave the other two comments, leaving only the one in question, invalid.
  3. Is MyBatis reading configuration elsewhere? So I comment out the configuration, and the result is a problem, indicating that this is the configuration to read.

Source code method is good

At this point, it’s been a long time, and things are getting weirder and weirder, but things happen for a reason, and there’s got to be something wrong. I really can’t find out the problem of the project itself. I can only suspect that there is something wrong with MyBatis. Maybe it really triggered the hidden bug of MyBatis.

This is not the only way to debug MyBatis source code. Want to, MyBatis source code I am still more familiar with. Let’s meet again for a while.

Mybatis – Spring-boot-Starter has only three Java files, of which MybatisAutoConfiguration is the key service class.


SqlSessionFactory (DataSource DataSource) = SqlSessionFactory (DataSource DataSource)

If it is the first time to debug the source code of the open source framework, often can not find the correct position, in fact, it does not matter, the breakpoint can be hit in any position, the worst thing is to slowly follow two times, itself read the source code, debugging process is a long process.

@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
 / / to omit...  if(! ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {  factory.setMapperLocations(this.properties.resolveMapperLocations());  }  return factory.getObject(); } Copy the code

The above code I only kept the problems related to the code, it is the process of resolving mapperLocations, namely in the code above this. The properties. The resolveMapperLocations () this method.

public Resource[] resolveMapperLocations() {
    ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
    List<Resource> resources = new ArrayList<Resource>();
    if (this.mapperLocations ! =null) {
      for (String mapperLocation : this.mapperLocations) {
 try {  Resource[] mappers = resourceResolver.getResources(mapperLocation);  resources.addAll(Arrays.asList(mappers));  } catch (IOException e) {  // ignore  }  }  }  return resources.toArray(new Resource[resources.size()]); } Copy the code

As I continued to track the code, MyBatis had indeed identified the three package paths in the configuration file. This. mapperLocations is an array of those three package paths.

Downwards and then, in the method resourceResolver. GetResources (mapperLocation) for each path parsing, discovered the first two packages all returned to the Resource [], which is corresponding to the XML file resources, while the last return indeed ShiKong array, The cause of the problem is close enough.

Then restart debugging, when parsing path is the final package, enter the resourceResolver. GetResources (mapperLocation) method, and see what the inside, finally found the following code, the call returns rootDirURL is an absolute path, This is the physical path where the XML resides.

URL rootDirURL = rootDirResource.getURL();
Copy the code

At this moment, finally found the problem, the absolute path should not XML path, but the other path under sub modules, by contrast, found that it turns out that child module was built a folder name, cause there are two identical package path, and the above code returns the absolute path of another package. So I contacted my colleague and asked why the package was created. It was recently added but no longer useful, so I deleted it and solved the problem.

This should be circumvented in normal project development. Modules should not have the same package name as modules, and should be named as follows:

ModuleA: com.kite.modulea

Module B: com. Kite. ModuleB

This fundamentally solves the problem to prevent unnecessary trouble.

The last

This exception of MyBatis is really a headache, because the cause of the error is not obvious, and so on, it is not easy to troubleshoot problems caused by XML files, most cases are caused by human negligence, and errors are generally hidden.

When a problem cannot be found and solved after multiple verification, it is often necessary to change the way of thinking. Jump out in time and re-examine the problem from other angles or at a higher level, so as to find the cause of the problem more quickly.

When using an open source framework, if you have a problem and can’t find a solution for a long time, you can try debugging the source code. It’s not as difficult as you might think.

Strong man wait, first give a praise bar, always white piao, the body can not bear!

I am kite, public id “ancient Time kite”, I have been working in the application circles for many years, mainly Java, Python, React also play very 6 slash developer. Can add my friends in the public account, into the group of small partners exchange learning, a lot of dachang students are also in the group yo.