Mybatis报错:Mapped Statements collection does not contain value for x包.x类.x方法

Mybatis报错:Mapped Statements collection does not contain value for x包.x类.x方法

 

错误信息:

### Error querying database.  Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.task.dao.ProductDao.selectByUserId

 

网上寻找原因:对应的Mapper映射文件没有被成功扫描到

  1. 命名空间没有设置对或映射文件名和对应接口名不一致

    <!--命名空间没问题-->
    <mapper namespace="com.task.dao.ProductDao">
    <!--映射文件名和对应接口名也一致-->
  2. 对应spring配置文件中的mybatis配置没有设置对

    <!--配置扫描也没问题-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="basePackage" value="com.task.dao" />
    </bean>
  3. maven编译后,target目录下没有生成对应的Mapper映射文件

    //对应target目录下也存在对应的Mapper映射文件

 

分析:

由于第一次使用spring中的ApplicationContextAware接口,并且这些方法都是在这里面执行的时候报错的。有可能是这里面的原因。

下面是实现ApplicationContextAware接口的类

public class StaticPageLoader implements ApplicationContextAware {
   
   @Autowired
   private InitService initService;
   
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       init();
  }
   
   public void init() {
       //这个会去调用对应UserDao
       initService.init();
  }
   
}

对应InitService中的方法

public class InitServiceImpl implements InitService {
   @Autowired
   private UserDao userDao;
  ...
   public void init() {
      ...
       userDao.selectDetailById();
      ...
  }
  ...
}

对应的Mapper映射文件

<!--会将查询的结果映射到下面的resultMap中-->
<select id="selectDetailById" resultMap="selectDetailByIdResultMap">
  SELECT * FROM t_user WHERE `id`=#{id}
</select>

<!--这里面有个select,会调用ProductDao.selectByUserId中的方法去查询-->
<!--报错就出在这里,但是对应的Dao和映射文件也没问题-->
<resultMap id="selectDetailByIdResultMap" type="com.task.pojo.User" extends="baseResultMap">
   <collection property="products" ofType="com.task.pojo.Product"
               select="com.task.dao.ProductDao.selectByUserId"
               column="id"
               ></collection>
</resultMap>

 

于是,我就在StaticPageLoader类中写了一个方法,直接调用ProductDao和UserDao,然后运行调试看看

public class StaticPageLoader implements ApplicationContextAware {
   
   @Autowired
   private InitService initService;
   
   @Autowired
   private ProductDao productDao;
   @Autowired
   private UserDao userDao;
   
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       test();
       init();
  }
   
   public void init() {
       //这个会去调用对应UserDao
       initService.init();
  }
   
   public void test() {
       System.out.println("测试。。。。。。。。。");
       productDao.selectByUserId(5);
       userDao.selectDetailById(5);
  }
   
}

结果,运行没有问题。

然后又测试了几次,发现只要在init方法之前注入UserDao就可以。

 

猜测原因

猜猜原因:执行实现ApplicationContextAware的类中的setApplicationContext方法时,并不是所有Bean都已经被加载到了容器中。如果要使用这些Bean,可以使用getBean等方法。

原因有待验证。。。

 

posted @ 2020-07-04 11:42  绘小雨  阅读(58)  评论(0编辑  收藏  举报