Why is Mybatis mapper scanner picking up wrong cla

2019-08-24 18:26发布

问题:

I use Spring with Mybatis. I have it configured to scan for mappers in my whole project and I assumed it determined a mapper because it found an XML file which has reference to a java interface.

But this is proven incorrect today because I had to add a new interface which is not a mapper class and Mybatis thinks it is, so it is causing problems in my app due to this error:

Mapped Statements collection does not contain value for com.blah.MyInterface.someMethod

com.blah.MyInterface is just a simple interface which I needed to be included in Spring context so I gave it the @Component tag. Is that the wrong tag to use? Is that where the confusion comes from?

I just needed to create this interface so that I can have a proxy wrap my database calls in one place where I can put a @Transactional tag, since Spring ignores it when it is in my Controller method.

Sample code

package com.blah.something;

@Component public interface MyInterface {

    public void someMethod( SomeObject obj) throws Exception; 
}


package com.blah.something;

public class MyImplementation implements MyInterface {

        @Transactional
        public void someMethod( SomeObject obj) throws Exception {
              ... do a whole bunch of stuff
        } 
}

I dont want this included in the MyBatis mappers!

Edit: added the mybatis config xml as requested:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="lazyLoadingEnabled" value="false" />
        <setting name="defaultStatementTimeout" value="60"/>
    </settings>

    <typeAliases>
      <typeAlias alias="StripTrailingZerosBigDecimalTypeHandler" type="com.blah.typehandlers.StripTrailingZerosBigDecimalTypeHandler"/>
    </typeAliases>

</configuration>

This is the part of my spring xml config which calls the mybatis mapper scanner:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.blah" />
</bean>

So I set it to scan the whole project which includes my interface above but I can't imagine it just grabs every single interface and considers them all mappers!

In my debug log I see mybatis picking up my interface:

12/9/13 11:18:44 904 [org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner.findCandidateComponents:4125] - Scanning file [D:\Weblogic\wls11\domains\ldapdomain\autodeploy\default\WEB-INF\classes\com\blah\MyInterface.class]
12/9/13 11:18:44 904 [org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner.findCandidateComponents:4125] - Identified candidate component class: file [D:\Weblogic\wls11\domains\ldapdomain\autodeploy\default\WEB-INF\classes\com\blah\MyInterface.class]
12/9/13 11:18:44 904 [org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner.findCandidateComponents:4125] - Scanning file [D:\Weblogic\wls11\domains\ldapdomain\autodeploy\default\WEB-INF\classes\com\blah\MyImplementation .class]
12/9/13 11:18:44 904 [org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner.findCandidateComponents:4125] - Ignored because not a concrete top-level class: file [D:\Weblogic\wls11\domains\ldapdomain\autodeploy\default\WEB-INF\classes\com\blah\MyImplementation .class]

There is no XML for this interface, there is no mapper namespace for it, it's just a plain old regular interface and MyBatis should not be thinking it is a mapper service

回答1:

Ok it looks like MyBAtis scanner does indeed take every interface, it does not have any "smarts" in it to identify mapper interfaces as I thought it would - based on finding matching XML or namespaces. I had to add a filter to the mapper configuration and then introduce a new annotation to annotate my mapper interfaces.