在最近進行的一個項目中學習了使用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:\IDEAProjects\mk-video\mk-video-mapper\target\classes\com\mk\mapper\UsersMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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:\IDEAProjects\mk-video\mk-video-mapper\target\classes\com\mk\mapper\UsersMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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:\IDEAProjects\mk-video\mk-video-mapper\target\classes\com\mk\mapper\UsersMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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:\IDEAProjects\mk-video\mk-video-mini-api\target\classes\mapper\BgmMapper.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,這里會拋出一些錯誤。考慮是否是自己某些文件中的代碼內容有誤或者有些文件不符合規范。每個人出現錯誤的地方有多種,希望本篇文章可以給遇到我這種類似的問題的童鞋一種方向。