【问题标题】:JPA XML Mapping file resolves just fine, but fails to resolve when running as a JUnit testJPA XML 映射文件解析得很好,但在作为 JUnit 测试运行时无法解析
【发布时间】:2016-12-06 01:33:52
【问题描述】:

我有一个带有 XML 设置实体管理器工厂的 spring 项目,其中一部分指向包含我所有查询的外部映射文件。

这是我正在使用的版本:

春季版:4.1.1.RELEASE

JUnit 版本:4.9

Spring-data-jpa 版本:1.7.1.RELEASE

Java 版本:1.8

这里的问题是,在我尝试将 JUnit 测试类添加到我的应用程序之前,我的项目运行良好。事实上,该项目以零错误开始,我可以顺利运行每个查询。现在我已经添加了一个测试类,它失败了,因为在单元测试期间它试图设置应用程序上下文并且无法解析我的映射文件。 (从我可以在堆栈跟踪中破译的内容)为什么??

我要加载的文件是queries.xml,它位于src/main/resources,下面是文件:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm 
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd" 
version="2.1">

<named-query name="GameSet.getNewTutorial">
    <query>
        <![CDATA[
            SELECT gs
            FROM GameSet gs
            WHERE gs.id.gameCatCd = :qstnSet
            AND gs.presetQstn.id.qstnSet = 'tutorials'
            ORDER BY gs.qstnOrder ASC
        ]]>
    </query>
</named-query>

<named-query name="WkstHdr.getExistingWorksheet">
    <query>
        <![CDATA[
            SELECT wh
            FROM WkstHdr wh
            WHERE wh.id.startDate BETWEEN :beginTimestamp AND :endTimestamp
            AND wh.id.warriorId = :warriorId
            AND wh.id.qstnSet = :qstnSet
        ]]>
    </query>
</named-query>

<named-query name="GameSet.getNewWorksheet">
    <query>
        <![CDATA[
            SELECT gs
            FROM GameSet gs
            WHERE gs.presetQstn.id.qstnSet = :qstnSet
        ]]>
    </query>
</named-query>

<named-query name="WkstVal.getExistingTutorial">
    <query>
        <![CDATA[
            SELECT v
            FROM WkstVal v
            WHERE v.id.warriorId = :warriorId
            AND v.id.gameCatCd = :qstnSet
            AND v.id.qstnSet = 'tutorials'
            ORDER BY v.gameSet.qstnOrder
        ]]>
    </query>
</named-query>

<named-native-query name="Score.getScore" result-set-mapping="ScoreMapping">
    <query>
        <![CDATA[
            SELECT sum(CASE WHEN v.bool_resp = true THEN pq.points ELSE 0 END) / :total AS points,
            sum(CASE WHEN ((v.game_cat_cd = 'summary') AND (v.game_sub_cat_cd = 'zone') AND (v.num_resp > 0)) THEN v.num_resp ELSE 0 END) /
            (CASE WHEN (CASE WHEN :total = 1 THEN 1 ELSE (sum(CASE WHEN ((v.game_cat_cd = 'summary') AND (v.game_sub_cat_cd = 'zone') AND (v.num_resp > 0)) THEN 1 ELSE 0 END)) END) > 0 THEN (CASE WHEN :total = 1 THEN 1 ELSE (sum(CASE WHEN ((v.game_cat_cd = 'summary') AND (v.game_sub_cat_cd = 'zone') AND (v.num_resp > 0)) THEN 1 ELSE 0 END)) END) ELSE 1 END) AS zone,
            sum(CASE WHEN ((v.game_cat_cd = 'summary') AND (v.game_sub_cat_cd = 'power')) THEN v.num_resp ELSE 0 END) / :total AS power
            FROM preset_qstn pq JOIN game_set gs JOIN wkst_hdr wh JOIN wkst_val v 
            ON wh.warrior_id = v.warrior_id
            AND wh.qstn_set = v.qstn_set
            AND wh.start_date = v.start_date 
            ON gs.game_cat_cd = v.game_cat_cd
            AND gs.game_sub_cat_cd = v.game_sub_cat_cd
            AND gs.game_cd = v.game_cd
            AND gs.qstn_cd = v.qstn_cd 
            ON pq.qstn_set = gs.qstn_set
            AND pq.qstn_cd = gs.qstn_cd
            WHERE wh.warrior_id = :warriorId
            AND wh.qstn_set = :qstnSet
            AND wh.start_date BETWEEN :beginTimestamp AND :endTimestamp
        ]]>
    </query>
</named-native-query>

<named-native-query name="Task.getTasks" result-set-mapping="TaskMapping">
    <query>
        <![CDATA[
            SELECT "public"."wkst_hdr"."start_date" AS startDate,
            "public"."wkst_hdr"."cmpl_date" AS cmplDate,
            "public"."wkst_val"."bool_resp" AS important,
            "public"."wkst_val"."txt_resp" AS description 
            FROM "public"."wkst_hdr" 
            JOIN "public"."wkst_val" 
            ON "public"."wkst_hdr"."warrior_id" = "public"."wkst_val"."warrior_id" 
            AND "public"."wkst_hdr"."start_date" = "public"."wkst_val"."start_date" 
            AND "public"."wkst_hdr"."qstn_set" = "public"."wkst_val"."qstn_set" 
            WHERE "public"."wkst_hdr"."warrior_id" = :warriorId 
            AND "public"."wkst_hdr"."qstn_set" = 'todos' 
            ORDER BY "public"."wkst_hdr"."start_date" DESC, 
            "public"."wkst_val"."bool_resp" DESC
        ]]>
    </query>
</named-native-query>

<sql-result-set-mapping name="ScoreMapping">
    <constructor-result target-class="com.wakeupwarrior.model.api.Score">
        <column name="zone" class="java.math.BigDecimal"/>
        <column name="points" class="java.math.BigDecimal"/>
        <column name="power" class="java.math.BigDecimal"/>
    </constructor-result>
</sql-result-set-mapping>

<sql-result-set-mapping name="TaskMapping">
    <constructor-result target-class="com.wakeupwarrior.model.api.Task">
        <column name="startDate" class="java.util.Date"/>
        <column name="cmplDate" class="java.util.Date"/>
        <column name="description" class="java.lang.String"/>
        <column name="important" class="java.lang.Boolean"/>
    </constructor-result>
</sql-result-set-mapping>

我有一个用于主应用程序的上下文文件和一个用于 JUnit 测试的上下文文件,它们完全相同。以下是我的上下文文件的副本:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

<!-- Enables the Spring MVC @Controller programming model and pageable -->  
<annotation-driven>
    <argument-resolvers>
        <beans:bean id="sortResolver" class="org.springframework.data.web.SortHandlerMethodArgumentResolver" />
        <beans:bean id="pageableResolver" class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
            <beans:constructor-arg ref="sortResolver" />
        </beans:bean>
    </argument-resolvers>
</annotation-driven>


<!-- Enables Spring to bootstrap the correct packages, looking for components -->
<context:component-scan base-package="com.slconnected.*" />
<context:component-scan base-package="com.wakeupwarrior.*" />


    <!-- Handles HTTP GET requests for the index.html file -->
<resources mapping="/*" location="/" />

<!-- Handles HTTP GET requests for /resources/** by serving static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<resources mapping="/node_modules/**" location="/node_modules/" />

<resources mapping="/themes/**" location="/themes/" />


<!-- Resolves messages on error inputs -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <beans:property name="basename" value="classpath:messages" />
</beans:bean>


<!-- Adds properties from warrior-db.properties -->
<beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <beans:property name="location" value="classpath:warrior-db.properties" />
</beans:bean>

<!-- Warrior DB data source with c3p0 connection pool-->
<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <!-- Connection properties -->
    <beans:property name="driverClass" value="${jdbc.driverClass}" />
    <beans:property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
    <beans:property name="user" value="${jdbc.user}" />
    <beans:property name="password" value="${jdbc.password}" />
    <!-- Pool properties -->
    <beans:property name="minPoolSize" value="${jdbc.minPoolSize}" />
    <beans:property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
    <beans:property name="acquireIncrement" value="${jdbc.acquireIncrement}" />
    <beans:property name="maxStatements" value="${jdbc.maxStatements}" />
    <beans:property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}" />
    <beans:property name="loginTimeout" value="${jdbc.loginTimeout}" />
</beans:bean>

<!-- Entity Manager Factory -->
<beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <beans:property name="dataSource" ref="dataSource" />
    <beans:property name="packagesToScan" value="com.wakeupwarrior.model.warriordb" />
    <beans:property name="mappingResources">
        <beans:list>
            <beans:value>
                classpath:queries.xml
            </beans:value>
        </beans:list>
    </beans:property>
    <beans:property name="jpaProperties">
        <beans:props>
            <beans:prop key="hibernate.current_session_context_class">
                org.springframework.orm.hibernate4.SpringSessionContext
            </beans:prop>
        </beans:props>
    </beans:property>
    <beans:property name="jpaVendorAdapter">
        <beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <beans:property name="databasePlatform" value="${jdbc.databasePlatform}" />
            <beans:property name="showSql" value="${jdbc.showSql}" />
        </beans:bean>
    </beans:property>
</beans:bean>

<!-- Transaction Manager -->
<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>

<!-- Enables Transactions -->
<tx:annotation-driven proxy-target-class="true" />

<!-- Annotation config -->
<context:annotation-config/>

如果我注释掉这部分:

<beans:property name="mappingResources"> <beans:list> <beans:value> classpath:queries.xml </beans:value> </beans:list> </beans:property>

一切似乎都运行良好! ..除了我现在不能使用我的查询,所以这并不能解决我的问题。

这是我尝试运行时得到的堆栈跟踪:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/slconnected/test/WarriorTests-context.xml]: Invocation of init method failed; nested exception is org.hibernate.boot.MappingException: Unable to resolve explicitly named mapping-file : 
                classpath:queries.xml
             : origin(
                classpath:queries.xml
            )
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:132)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:59)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:260)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:63)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:83)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:74)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:169)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:109)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:199)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:251)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:253)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.hibernate.boot.MappingException: Unable to resolve explicitly named mapping-file : 
                classpath:queries.xml
             : origin(
                classpath:queries.xml
            )
at org.hibernate.boot.model.process.internal.ScanningCoordinator.applyScanResultsToManagedResources(ScanningCoordinator.java:213)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:81)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:98)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:200)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:150)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider$1.<init>(SpringHibernateJpaPersistenceProvider.java:49)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:49)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 40 more
ERROR: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@31f924f5] to prepare test instance [com.slconnected.test.WarriorTests@27dc79f7]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:91)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:74)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:169)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:109)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:199)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:251)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:253)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/slconnected/test/WarriorTests-context.xml]: Invocation of init method failed; nested exception is org.hibernate.boot.MappingException: Unable to resolve explicitly named mapping-file : 
                classpath:queries.xml
             : origin(
                classpath:queries.xml
            )
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:132)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:59)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:260)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:63)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:83)
... 25 more
Caused by: org.hibernate.boot.MappingException: Unable to resolve explicitly named mapping-file : 
                classpath:queries.xml
             : origin(
                classpath:queries.xml
            )
at org.hibernate.boot.model.process.internal.ScanningCoordinator.applyScanResultsToManagedResources(ScanningCoordinator.java:213)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:81)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:98)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:200)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:150)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider$1.<init>(SpringHibernateJpaPersistenceProvider.java:49)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:49)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 40 more

同样,正常运行项目时一切运行良好。只有当我将它作为测试用例运行时,或者当我进入构建的测试部分时,我才会收到此错误。这里发生了什么?在单元测试期间如何让它与我的外部 query.xml 文件一起工作?

【问题讨论】:

    标签: java xml spring jpa junit


    【解决方案1】:

    我想通了!!!!

    我花了几天时间在调试器中单步执行数千行代码,直到我能够观察问题的实际情况。事实证明,hibernate org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl 深处的类中有一行代码,它尝试使用以下代码在类路径中定位文件:

    final URL url = getAggregatedClassLoader().getResource( name );
            if ( url != null ) {
                return url;
            }
    

    这里总共有两个问题。首先,在尝试解析文件时文件名字符串所遵循的过程不允许剥离从queries.xml 文件复制的换行符和空格。最后一个问题是,如果您在生产期间不附加 classpath:getResource() 返回 null,但如果您在作为 JUnit 运行时附加 classpath:,则返回 null。我不知道为什么会发生这种情况,但确实如此。因此,我的解决方案是修改用于 JUnit 测试的上下文文件以使用:

    <beans:property name="mappingResources">
            <beans:list>
                <beans:value>queries.xml</beans:value>
            </beans:list>
        </beans:property>
    

    代替:

    <beans:property name="mappingResources">
            <beans:list>
                <beans:value>
                    classpath:queries.xml
                </beans:value>
            </beans:list>
        </beans:property>
    

    因此,我最终得到了修改后的测试应用程序上下文,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    
    
    <!-- Enables Spring to bootstrap the correct packages, looking for components -->
    <context:component-scan base-package="com.slconnected.*" />
    <context:component-scan base-package="com.wakeupwarrior.*" />
    
    
    <!-- Enables the Spring MVC @Controller programming model and pageable -->  
    <annotation-driven>
        <argument-resolvers>
            <beans:bean id="sortResolver" class="org.springframework.data.web.SortHandlerMethodArgumentResolver" />
            <beans:bean id="pageableResolver" class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
                <beans:constructor-arg ref="sortResolver" />
            </beans:bean>
        </argument-resolvers>
    </annotation-driven>
    
    
    <!-- Handles HTTP GET requests for the index.html file -->
    <resources mapping="/*" location="/" />
    
    <!-- Handles HTTP GET requests for /resources/** by serving static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />
    
    <resources mapping="/node_modules/**" location="/node_modules/" />
    
    <resources mapping="/themes/**" location="/themes/" />
    
    
    <!-- Resolves messages on error inputs -->
    <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <beans:property name="basename" value="classpath:messages" />
    </beans:bean>
    
    
    <!-- View resolver that works by registering beans with names -->
    <beans:bean id="beanNameResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <beans:property name="order" value="1" />
    </beans:bean>
    
    <!-- The Birt engine factory -->
    <beans:bean id="engine" class="com.wakeupwarrior.reports.core.BirtEngineFactory" />
    
    <!-- Resolves POWER FOCUS HTML view -->
    <beans:bean name="html/powerFocus" id="html/powerFocus" class="com.wakeupwarrior.reports.core.HtmlSingleFormatBirtView">
        <beans:property name="birtEngine" ref="engine" />
        <beans:property name="dataSource" ref="dataSource" />
        <beans:property name="reportName" value="power_focus.rptdesign" />
        <beans:property name="reportsDirectory" value="reports" />  
    </beans:bean>
    
    <!-- Resolves TESTER HTML view -->
    <beans:bean name="html/tester" id="html/tester" class="com.wakeupwarrior.reports.core.HtmlSingleFormatBirtView">
        <beans:property name="birtEngine" ref="engine" />
        <beans:property name="dataSource" ref="dataSource" />
        <beans:property name="reportName" value="tester.rptdesign" />
        <beans:property name="reportsDirectory" value="reports" />  
    </beans:bean>   
    
    
    <!-- Adds properties from warrior-db.properties -->
    <beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <beans:property name="location" value="classpath:warrior-db.properties" />
    </beans:bean>
    
    <!-- Warrior DB data source with c3p0 connection pool-->
    <beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- Connection properties -->
        <beans:property name="driverClass" value="${jdbc.driverClass}" />
        <beans:property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
        <beans:property name="user" value="${jdbc.user}" />
        <beans:property name="password" value="${jdbc.password}" />
        <!-- Pool properties -->
        <beans:property name="minPoolSize" value="${jdbc.minPoolSize}" />
        <beans:property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
        <beans:property name="acquireIncrement" value="${jdbc.acquireIncrement}" />
        <beans:property name="maxStatements" value="${jdbc.maxStatements}" />
        <beans:property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}" />
        <beans:property name="loginTimeout" value="${jdbc.loginTimeout}" />
    </beans:bean>
    
    <!-- Entity Manager Factory -->
    <beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <beans:property name="dataSource" ref="dataSource" />
        <beans:property name="packagesToScan" value="com.wakeupwarrior.model.*" />
        <beans:property name="mappingResources">
            <beans:list>
                <beans:value>queries.xml</beans:value>
            </beans:list>
        </beans:property>
        <beans:property name="jpaProperties">
            <beans:props>
                <beans:prop key="hibernate.current_session_context_class">
                    org.springframework.orm.hibernate4.SpringSessionContext
                </beans:prop>
            </beans:props>
        </beans:property>
        <beans:property name="jpaVendorAdapter">
            <beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <beans:property name="databasePlatform" value="${jdbc.databasePlatform}" />
                <beans:property name="showSql" value="${jdbc.showSql}" />
            </beans:bean>
        </beans:property>
    </beans:bean>
    
    <!-- Transaction Manager -->
    <beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <beans:property name="entityManagerFactory" ref="entityManagerFactory" />
    </beans:bean>
    
    <!-- Enables Transactions -->
    <tx:annotation-driven proxy-target-class="true" />
    
    <!-- Annotation config -->
    <context:annotation-config/>
    

    现在完美运行!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2015-10-09
      • 2016-07-03
      相关资源
      最近更新 更多