java - JPA XML 映射文件可以很好地解析,但在作为 JUnit 测试运行时无法解析

标签 java xml spring jpa junit

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

以下是我正在使用的版本:

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 文件一起使用?

最佳答案

我明白了!!!

我花了几天时间在调试器中单步调试数千行代码,直到能够观察问题的实际情况。事实证明,在 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/>

现在完美运行!

关于java - JPA XML 映射文件可以很好地解析,但在作为 JUnit 测试运行时无法解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40986378/

相关文章:

java - Jenkins 在执行 JUnit 测试时出现 Java 堆空间异常

Java:对象与条件的关系( hibernate )

Spring Cloud DataFlow 文档缺少部分

java - Spring data JPA 获取数据作为对象列表的流

java - Weka 异常 : No source has been specified

java - 在 hibernate 状态下是否可能有两次相同的 "OneToOne"-Relationship ?

ios - NSXMLParserErrorMessage 内部错误 : Huge input lookup

java - jaxb-bindingx.xml “results in too many target nodes”

c# - 使用 XElement 作为模板将 DataTable 转换为 XML

java - 使用 RestTemplate 解析本地 JSON 文件