在最近进行的一个项目中学习了使用Spring boot框架的开发,在整合Mybatis开发时,项目一启动就报如下错误:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2019-05-18 17:01:35,065 [main] [org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:858)] - [ERROR] Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'registerLoginController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'usersMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usersMapper' defined in file [D:IDEAProjectsmk-videomk-video-mapper argetclassescommkmapperUsersMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [tk/mybatis/mapper/autoconfigure/MapperAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey at com.mk.Application.main(Application.java:14) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'usersMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usersMapper' defined in file [D:IDEAProjectsmk-videomk-video-mapper argetclassescommkmapperUsersMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [tk/mybatis/mapper/autoconfigure/MapperAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey
... 19 more Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usersMapper' defined in file [D:IDEAProjectsmk-videomk-video-mapper argetclassescommkmapperUsersMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [tk/mybatis/mapper/autoconfigure/MapperAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey ... 32 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [tk/mybatis/mapper/autoconfigure/MapperAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey ... 43 more Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey ... 56 more Caused by: org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:IDEAProjectsmk-videomk-video-mini-api argetclassesmapperBgmMapper.xml]'; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey ... 57 more Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mk.mapper.BgmMapper.selectByPrimaryKey ... 70 more
在网上看到了许多人都经历过类似的错误,归纳起来有:
- Application启动类放置位置问题
- 注解配置不完整,如Service实现类没有加@Service,Spring boot无法扫描等
- 配置文件等内容有误
- Jar包冲突
关于这些问题可以参考这篇博客:
https://blog.csdn.net/zjh_746140129/article/details/80156223
最初本人的原因是无法使用@Autowired 在ServiceImpl中注入mapper,是因为Spring boot无法识别mapper,最后在mapper接口上加上@Repository和在Application类上加上@MapperScan(basePackges="com.mk.mapper")解决,但最后项目一直报开始提到的错误。
在确定不是以上问题后,使用debugger开始跟踪过程,发现了这个:
解析映射资源失败,说明我的mapper.xml文件有问题。我的mapper和pojo文件是使用Mybatis逆向工程生成的,这是之前开发Spring MVC项目时配置的一个逆向工程,生成的mapper.xml文件如下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.mk.mapper.BgmMapper" > <resultMap id="BaseResultMap" type="com.mk.pojo.Bgm" > <id column="id" property="id" jdbcType="VARCHAR" /> <result column="author" property="author" jdbcType="VARCHAR" /> <result column="name" property="name" jdbcType="VARCHAR" /> <result column="path" property="path" jdbcType="VARCHAR" /> </resultMap> <sql id="Example_Where_Clause" > ...... </sql> <sql id="Update_By_Example_Where_Clause" > ...... </sql> <sql id="Base_Column_List" > id, author, name, path </sql> <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.mk.pojo.BgmExample" > select <if test="distinct" > distinct </if> <include refid="Base_Column_List" /> from bgm <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> <if test="orderByClause != null" > order by ${orderByClause} </if> </select> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" > select <include refid="Base_Column_List" /> from bgm where id = #{id,jdbcType=VARCHAR} </select> ......
可以看出来是非常长的,后来换了另一种逆向工程方式,生成的pojo类并不包含XxxExample类,并且mapper.xml也非常清爽,如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.mk.mapper.BgmMapper" > <resultMap id="BaseResultMap" type="com.mk.pojo.Bgm" > <!-- WARNING - @mbg.generated --> <id column="id" property="id" jdbcType="VARCHAR" /> <result column="author" property="author" jdbcType="VARCHAR" /> <result column="name" property="name" jdbcType="VARCHAR" /> <result column="path" property="path" jdbcType="VARCHAR" /> </resultMap> </mapper>
替换掉pojo和mapper之后,系统启动正常,虽然目前我还不明白这两种方式的区别以及对项目的影响,如有人知道,请不吝指教。
所以看到这里,想告诉大家的是,如果出现这个问题不是上述提到的4种常见错误外,尝试debugger一下,最好断点设置在sqlSessionFactory处,因为一般项目初始无法启动时是因为无法创建bean,这里会抛出一些错误。考虑是否是自己某些文件中的代码内容有误或者有些文件不符合规范。每个人出现错误的地方有多种,希望本篇文章可以给遇到我这种类似的问题的童鞋一种方向。