SpringMVC+Mybatis异常解决

今天在IDEA(Maven)整合SpringMVC和Mybatis时,在Spring-mybatis.xml中设置了自动扫描mapping.xml文件。配置如下

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:com/ojdbc/hello/mapping/*.xml"></property>
</bean>

结果在启动Tomcat时报错(省略部分代码):

[org.springframework.web.context.support.XmlWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [org.springframework.core.io.Resource[]] for property 'mapperLocations'; nested exception is java.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:com/ojdbc/hello/mapping/*.xml]: class path resource [com/ojdbc/hello/mapping/] cannot be resolved to URL because it does not exist
[org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [org.springframework.core.io.Resource[]] for property 'mapperLocations'; nested exception is java.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:com/ojdbc/hello/mapping/*.xml]: class path resource [com/ojdbc/hello/mapping/] cannot be resolved to URL because it does not exist
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)

从异常信息行:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [org.springframework.core.io.Resource[]] for property 'mapperLocations'; nested exception is java https://pharmacieinde...ce.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:com/ojdbc/hello/mapping/*.xml]: class path resource [com/ojdbc/hello/mapping/] cannot be resolved to URL because it does not exist

从后往前看,最根本的原因是不能将“classpath:com/ojdbc/hello/mapping/*.xml”转成URL。再往前看发现是不能由于不能识别正则通配符“*”。

经测试将“classpath:com/ojdbc/hello/mapping/*.xml”修改成“classpath*:com/ojdbc/hello/mapping/*.xml”后问题解决。

后来访问页面时又提示异常:

java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for demo1

 

分析其原因应该是没找到mapping.xml文件,导致mybatis不能访问到要执行的sql。

结合两个问题及生成的war包,应该是Maven在生成war包时没有将源码包中的xml文件添加到war包中,导致运行时找不到所对应的mapping文件。

猜测原因:使用“classpath*”的方式引入mapping文件是不会立刻验证文件是否存在,而不带星号的在初始化时就会验证文件是否存在,导致刚开始的时候出错。

解决方法为在Maven的pom.xml中增加以下代码:

<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

而此时classpath可以直接使用,不用加星号

此条目发表在技术, 未分类分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。