【问题标题】:JUnit test with JPA & Hibernate : Persistence.xml使用 JPA 和 Hibernate 进行 JUnit 测试:Persistence.xml
【发布时间】:2017-05-04 05:59:09
【问题描述】:

我正在使用 3 层:服务、业务和持久性。我想测试每一层。所以,我用我的测试文件创建了一个 src/test/java 文件夹,并为持久性文件(persistence.xml 和 data.sql)创建了一个 src/test/resources。我在每一层设置了这两个文件夹。但是当我想测试业务层时,我得到了以下错误:

SEVERE - Unable to load Persistence Unit from EAR: C:\dev\prj\myProject\persistence\\classpath.ear, module: file:/c:/dev/myProject/persistence/target/classes/. Exception: unexpected element (uri:"http://xmlns.jcp.org/xml/ns/persistence", local:"persistence"). Expected elements are <{http://java.sun.com/xml/ns/persistence}persistence>
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://xmlns.jcp.org/xml/ns/persistence", local:"persistence"). Expected elements are <{http://java.sun.com/xml/ns/persistence}persistence>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
    at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:150)
    at org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:551)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:380)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:619)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3129)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:504)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:357)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:258)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:229)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
    at org.apache.openejb.jee.jpa.unit.JaxbPersistenceFactory.getPersistence(JaxbPersistenceFactory.java:64)
    at org.apache.openejb.config.ReadDescriptors.deploy(ReadDescriptors.java:180)
    at org.apache.openejb.config.ConfigurationFactory$Chain.deploy(ConfigurationFactory.java:403)
    at org.apache.openejb.config.ConfigurationFactory.configureApplication(ConfigurationFactory.java:971)
    at org.apache.openejb.config.ConfigurationFactory.configureApplication(ConfigurationFactory.java:832)
    at org.apache.openejb.config.ConfigurationFactory.getOpenEjbConfiguration(ConfigurationFactory.java:546)
    at org.apache.openejb.config.ConfigurationFactory.getOpenEjbConfiguration(ConfigurationFactory.java:591)
    at org.apache.openejb.assembler.classic.Assembler.getOpenEjbConfiguration(Assembler.java:484)
    at org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:463)
    at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:151)
    at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:68)
    at org.apache.openejb.OpenEJB.init(OpenEJB.java:309)
    at org.apache.openejb.OpenEJB.init(OpenEJB.java:289)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.openejb.loader.OpenEJBInstance.init(OpenEJBInstance.java:36)
    at org.apache.openejb.core.LocalInitialContextFactory.init(LocalInitialContextFactory.java:98)
    at org.apache.openejb.core.LocalInitialContextFactory.init(LocalInitialContextFactory.java:62)
    at org.apache.openejb.core.LocalInitialContextFactory.getInitialContext(LocalInitialContextFactory.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.<init>(InitialContext.java:216)
    at be.smals.dos.engine.persistence.test.WorkflowDaoTest.setUp(WorkflowDaoTest.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

经过一些研究,我们似乎不能拥有多个persistence.xml。 为了解决这个问题,我尝试了以下解决方案:

  1. 将业务层的xml文件替换为持久层。于是测试运行业务层的persistence.xml。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.8</version>
	<executions>
	  <execution>
		<id>copy-test-persistence</id>
		<phase>process-test-resources</phase>
		<goals>
		  <goal>run</goal>
		</goals>
		<configuration>
		  <tasks>
			<!-- backup the "src" persistence.xml -->
			<move file="${project.build.outputDirectory}/META-INF/persistence.xml"
				  tofile="${project.build.outputDirectory}/META-INF/persistence.xml.src"/>
			<!-- copy the "test" persistence.xml -->
			<copy file="${project.build.testOutputDirectory}/META-INF/persistence.xml"
				  tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
			<!-- backup the "src" dos-engine-data.sql -->
			<move file="${project.build.outputDirectory}/data.sql"
				  tofile="${project.build.outputDirectory}/data.sql.src"/>
			<!-- copy the "test" dos-engine-data.sql -->
			<copy file="${project.build.testOutputDirectory}/data.sql"
				  tofile="${project.build.outputDirectory}/data.sql"/>
		  </tasks>
		</configuration>
	  </execution>
	  <execution>
		<id>restore-persistence</id>
		<phase>prepare-package</phase>
		<goals>
		  <goal>run</goal>
		</goals>
		<configuration>
		  <tasks>
			<!-- restore the "src" persistence.xml -->
			<move file="${project.build.outputDirectory}/META-INF/persistence.xml.src"
				  tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
			<!-- restore the "src" dos-engine-data.sql -->
			<move file="${project.build.outputDirectory}/data.sql.src"
				  tofile="${project.build.outputDirectory}/data.sql"/>
		  </tasks>
		</configuration>
	  </execution>
	</executions>
</plugin>
  1. 创建第二个 jar,但没有任何 persistence.xml。并指出当我们运行测试时,我们必须使用这些 JAR。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-jar-plugin</artifactId>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>jar</goal>
			</goals>
			<configuration>
				<finalName>jarName</finalName>
				<includes>
					<include>pathWithPersistenceFile</include>
				</includes>
			</configuration>
		</execution>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>jar</goal>
			</goals>
			<configuration>
				<finalName>jarNameTest</finalName>
				<classifier>test</classifier>
				<includes>
					<include>pathWithoutPersistenceFile</include>
				</includes>
			</configuration>
		</execution>
	</executions>
</plugin>

这两种解决方案不适用于我的情况。是否还有其他问题可以与多个 persistence.xml 一起使用?是否有可能指定其他持久性文件路径但没有 Spring 的解决方案?在这个项目中,我正在使用 Maven、Hibernate 和 H2 mem。

我花了几天时间为我的具体问题寻找解决方案,但我没有找到对我的问题有帮助的东西。

有人知道吗?

谢谢

【问题讨论】:

  • 为什么不通过模拟其他层来测试每一层?
  • 您不会碰巧在maintest 目标中使用不同的XML 命名空间吗? XML 命名空间在 JPA 2.0 和 2.1 之间进行了更改。见这里oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/…
  • @Jobin,谢谢你的回答。但我不能模拟其他层,因为我也需要其他层的真实行为。
  • @coladict,我已经在主要目标和测试目标中使用了不同的 XML 命名空间,因为 JUnit 需要 1.0 版本。
  • @bibi 你在用spring吗?

标签: java xml hibernate maven jakarta-ee


【解决方案1】:

一种解决方案是使用 Arquillian,例如:http://www.oracle.com/technetwork/articles/java/integrationtesting-487452.html

创建存档时,您可以覆盖persistence.xml

ShrinkWrap.addAsResource("your-persistence.xml", "META-INF/persistence.xml")

这样您就可以拥有任意数量的 your-persistence.xml,并且只需在单独的测试套件中重新覆盖它。

【讨论】:

  • 感谢您的回答。但是这个项目我不能使用 Arquillian。
猜你喜欢
  • 2012-07-23
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2015-06-23
  • 1970-01-01
  • 2014-09-30
  • 2011-10-11
相关资源
最近更新 更多