zoukankan      html  css  js  c++  java
  • 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等方法。

    原因有待验证。。。

     

  • 相关阅读:
    浅析TCP /UDP/ IP协议
    大小端模式
    小技巧—计算内存
    浅谈启发式合并
    浅谈换根DP
    POJ 3585 Accumulation Degree
    OSGi类加载问题
    Redis缓存集群方案
    Tair分布式缓存
    Tedis:淘宝的Redis的Java客户端开发包
  • 原文地址:https://www.cnblogs.com/rismer/p/13234367.html
Copyright © 2011-2022 走看看