mybatis和spring整合时这个报错,应该这样解决!
01
问题描述
今天在写mybatis和spring整合的时候,出现了个问题,其实也没有多难,就是自己没有仔细看,特此记录一下。
报错问题如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'empService' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.mybatis.spring.mapper.MapperScannerConfigurer' to required type 'org.dao.EmpDaoMapper' for property 'empDao'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.mybatis.spring.mapper.MapperScannerConfigurer] to required type [org.dao.EmpDaoMapper] for property 'empDao': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at org.test.TestMain.before(TestMain.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.mybatis.spring.mapper.MapperScannerConfigurer' to required type 'org.dao.EmpDaoMapper' for property 'empDao'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.mybatis.spring.mapper.MapperScannerConfigurer] to required type [org.dao.EmpDaoMapper] for property 'empDao': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:464)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:495)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:489)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1465)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1424)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 34 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.mybatis.spring.mapper.MapperScannerConfigurer] to required type [org.dao.EmpDaoMapper] for property 'empDao': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:449)
... 40 more
下面是spring的所有配置文件信息:
配置数据源信息:
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/schooldb"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
配置SqlSessionFactory信息,以及加载数据源:
<!-- 加载数据源 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 配置mapper属性 -->
<property name="mapperLocations">
<list>
<value>classpath:org/dao/*/*.xml</value>
</list>
</property>
<!-- 配置mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
使用MapperScannerConfigurer注入映射器:
<!-- 使用MapperScannerConfigurer -->
<bean id="empDao" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.dao"></property>
</bean>
下面就是配置Service层:
<bean id="empService" class="org.service.impl.EmpServiceImpl">
<property name="empDao" ref="empDao"></property>
</bean>
问题就出在“配置Service层”这一步,原来在未使用MapperScannerConfigurer的时候,程序是可以正常跑起来的,但是加上MapperScannerConfigurer,程序就报错,找了好半天,终于发现,原来粗心的将对象名写错了,下面是问题的解决方式:
02
解决问题
更正MapperScannerConfigurer注入映射器和empService注入映射器,代码如下:
<!-- 使用MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.dao"></property>
</bean>
<bean id="empService" class="org.service.impl.EmpServiceImpl">
<property name="empDao" ref="empDaoMapper"></property>
</bean>
然后运行项目,正常执行:
03
分析问题
当我们使用MapperScannerConfigurer注入映射器时,可以不用Mapper的实现类,但是Mapper的接口名必须要与所对应的SQL映射文件名一模一样,且接口中的方法名需与SQL映射文件的id名相同。
通过MapperScannerConfigurer可以批量生成映射器实现,映射器被注册到Spring的容器时,spring会自动根据其接口名给其命名,默认规则是首字母小写的非完全限定名。比如上面代码中的接口名为EmpDaoMapper,那默认命名就是empDaoMapper,原来在ref引入对象的时候,写的是empDao,所以就报错。改成其默认的命名empDaoMapper问题解决。
希望大家在整合框架的时候,能认真细心,避免出现没必要的bug,耽误时间。
辣椒酱,了解下呗~
往期精彩
点分享
点点赞
点在看