Tkmybatis集成动态数据源出现Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory metho

一、问题背景

     项目使用了mybatis与Tkmybatis的架构,这两种架构完全可以单独使用,但项目残留下来的写法让人心伤,鉴于这种情况存在,楼主决定采取TKmybatis的架构。

   TkMybatis的mapper的写法及相关包如下:

<!-- https://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter -->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>

代码:

import tk.mybatis.mapper.common.Mapper;


public interface SysUserMapper extends Mapper<SysUser> {

}

增加注解:import tk.mybatis.spring.annotation.MapperScan: @MapperScan("cn.com.web.mapper")

启动部分报错信息:

1、org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'authController': Unsatisfied dependency expressed through field 'systemService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'systemService': Unsatisfied dependency expressed through field 'sysUserMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysUserMapper' defined in file [E:\gitWorkSpace\bm-wechat-ling-framework\bm-wechat-ling-admin\target\classes\cn\com\bluemoon\admin\web\mapper\SysUserMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamicSqlSessionFactory' defined in class path resource [cn/com/bluemoon/mybatis/datasource/DataSourceConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'dynamicSqlSessionFactory' threw exception; nested exception is cn.com.bluemoon.mybatis.Exception.WebException

2、Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamicSqlSessionFactory' defined in class path resource [cn/com/bluemoon/mybatis/datasource/DataSourceConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'dynamicSqlSessionFactory' threw exception; nested exception is cn.com.bluemoon.mybatis.Exception.WebException

二、解决方案

 1、看到报错,还以为是bean初始化过程,于是根据:Unsatisfied dependency expressed through bean property 'sqlSessionFactory'   网上查找答案,看到比较多点赞文章如下:https://blog.csdn.net/sinat_34104446/article/details/83473712

主要围绕以下几点说明:

 1)、配置文件: ,

mybatis.mapper-locations = classpath*:mapper/*.xml
mybatis.config-location = classpath:mybatis-config.xml

classpath*:mapper/*.xml  与 classpath:mapper/*.xml  区别

扫描二维码关注公众号,回复: 12601928 查看本文章

      classpath:只会到你的class路径中查找找文件; 
      classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 

2)、mapper的接口路径与 *.xml 文件是否对上。

3)、启动时增加的注解是否没有引入其他其他包:@MapperScan({"cn.com.web.mapper","cn.com.admin.mapper"})

2、按步骤1检查一遍,发现都符合要求,于是决定debug,根据以下提示:

     Error creating bean with name 'dynamicSqlSessionFactory' defined in class path resource [cn/com/bluemoon/mybatis/datasource/DataSourceConfig.class]

找到 DataSourceConfig 的 dynamicSqlSessionFactory 方法,如下图:

当执行到箭头的时候报错,于是debug进入这个方法,其他执行的过程,此处忽略。最后进入 SqlSessionFactoryBean的 buildSqlSessionFactory() 方法。

如下图:

如上图异常部分,copy  value 值,如下:

  java.lang.IllegalArgumentException: Mapped Statements collection already contains value for cn.com.bluemoon.admin.web.mapper.SysMenuMapper.insert.
  please check file [E:\gitWorkSpace\bm-wechat-ling-framework\bm-wechat-ling-admin\target\classes\mapper\SysMenuMapper.xml] and 
  cn/com/bluemoon/admin/web/mapper/SysMenuMapper.java (best guess)

根据以上提示,错误基本定位到了:mapper接口已经存在 insert 方法,现在的SysMenuMapper的接口中也存在insert方法.

解决策略:基于tk.mybatis的架构,已经实现了增删改查的方法,以前残留下来的insert方法去掉,完美解决。

原因:mapper接口的方法即:cn.com.bluemoon.admin.web.mapper.SysMenuMapper.insert 映射到xml文件,既是:(namespace+ select,update,delete,insert的id)的组合id必须唯一。此处xml出现两个insert方法:一个是xml文件insert方法,一个是tkmybatis封装好的insert方法,删掉xml的insert方法,就可以了。

三、心得

    1、趋于统一技术栈的想法,因其他项目都在使用tk.mybatis,也为了方便维护,于是进行了调整。没想到遇到的坑,尽然花费我好几个小时去排查。。。

    2、遇事不要慌,稳住心态。网上的教程,只是提供一个排查问题的思路,具体问题具体分析,开启debug模式,一步一步找到抛出异常的节点,根据这个节点的具体异常信息进行排雷,胜利就在我们面前。

猜你喜欢

转载自blog.csdn.net/baidu_28068985/article/details/111286064