我有一组基于分层架构定义的maven项目,如下:
1-域
-src/main/java
-src/main/resources/META-INF/
-src/test/java
-src/test/resources/META-INF/
2- 存储库(取决于域)
-src/main/java
-src/main/resources/META-INF/
-src/test/java
-src/test/resources/spring/my-appcontext.xml
-src/test/resources/META-INF/orm.xml
我在存储库层的单元测试将 DbUnit 与 hsql 内存数据库结合使用。持久化配置基于JPA/Hibernate,通过spring配置。下面是我在测试中使用的弹簧配置示例:
<!-- our datasource -->
<bean id="myDatasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</bean>
<!-- let hibernate be in between the database and JPA -->
<bean id="myJpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="${jpa.database}" />
<property name="showSql" value="${jpa.showSql}" />
<property name="generateDdl" value="${jpa.generateDdl}" />
<property name="databasePlatform" value="${jpa.databasePlatform}" />
</bean>
<!-- entityManagerFactory - CONTAINER-managed -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="molecularanalysisDatasource"
p:mappingResources="${jpa.orm}"
p:packagesToScan="com.mypackages.domain">
<property name="jpaVendorAdapter" ref="myJpaVendorAdapter" />
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.showSql">${hibernate.showSql}</prop>
<prop key="hibernate.formatSql">${hibernate.formatSql}</prop>
<prop key="dialect">${hibernate.dialect}</prop>
<prop key="hibernate.connection.driver_class">${datasource.driverClass}</prop>
<prop key="hibernate.connection.url">${datasource.url}</prop>
<prop key="hibernate.connection.username">${datasource.username}</prop>
<prop key="hibernate.connection.password">${datasource.password}</prop>
</props>
</property>
</bean>
<bean id="dbUnitDatabaseConfig"
class="com.github.springtestdbunit.bean.DatabaseConfigBean">
<property name="qualifiedTableNames" value="true" />
</bean>
<bean id="dbUnitDatabaseConnection"
class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean">
<property name="dataSource" ref="myDatasource" />
<property name="databaseConfig" ref="dbUnitDatabaseConfig" />
<property name="schema" value="${datasource.schema}" />
</bean>
我在测试范围内使用的 orm.xml 确保表是在默认目录名称 PUBLIC 下的 hsqldb 中创建的。换句话说,在测试范围内使用 orm.xml 确保我的测试不关心域实体上定义的特定目录/模式名称,而只使用 hsqldb 下的默认目录(这是因为 hsql 只允许一个目录,即 PUBLIC)在测试期间创建表时。
当我使用 Eclipse 运行测试时,可以找到“src/test/resources/META-INF/orm.xml”下的 orm.xml,并且 entitymanagerfactory 使用它在 hsqldb 中创建表。但是,如果我使用 maven 运行测试,则不会拾取 orm.xml,因此 entitymanager 会尝试使用真实的目录和模式名称创建我的表(实体),这在 hsqldb 中将失败,因为它只有一个目录,即PUBLIC。
在 spring 中启用调试后,我注意到这是因为 entitymanagerfactory 在配置 Jpa/Hibernate 和持久性对象时使用不同的“root Url”来搜索配置文件。
在通过 Eclipse 运行测试的情况下,实体管理器使用可以找到 META-INF/orm.xml 的“target/test-classes/”目录。在通过 Maven 运行测试的情况下,实体管理器使用 domain.jar,其中不包括 META-INF/orm.xml(因为这仅在集成模块内的测试中定义)。在调试信息下方:
1-通过 Eclipse 运行测试:
[main] DEBUG - Processing PersistenceUnitInfo [
name: default
persistence provider classname: null
classloader: sun.misc.Launcher$AppClassLoader@35a16869
Temporary classloader:
org.springframework.instrument.classloading.SimpleThrowawayClassLoader@706f2039
excludeUnlistedClasses: true
JTA datasource: null
Transaction type: RESOURCE_LOCAL
PU root URL: file:/C:/DEVELOPMENT/project/integration/test-classes/
Shared Cache Mode: UNSPECIFIED
Validation Mode: AUTO
Jar files URLs []
2-通过Maven运行测试:
[main] DEBUG - Processing PersistenceUnitInfo [
name: default
persistence provider classname: null
classloader: sun.misc.Launcher$AppClassLoader@35a16869
Temporary classloader:
org.springframework.instrument.classloading.SimpleThrowawayClassLoader@706f2039
excludeUnlistedClasses: true
JTA datasource: null
Transaction type: RESOURCE_LOCAL
PU root URL: file:/C:/DEVELOPMENT/project/maven-repository/domain/domain.jar
Shared Cache Mode: UNSPECIFIED
Validation Mode: AUTO
Jar files URLs []
我无法工作的是如何让 entitymanager 在扫描 orm.xml 文件时包含 META-INF/orm.xml。有谁知道如何在 Maven 中进行测试?将此 orm.xml 添加到域 (src/main/resources/META-INF) 将无济于事,因为此设置仅应在测试上下文中使用。