2012-03-28 22 views
6

好的,很抱歉,我查找了幾個小時的答案,但是我花了整個StackOverflow的問題來冒出我想找的鏈接。您可以閱讀很多相關信息here使用單獨的persistence.xml文件進行生產並使用Spring 3.1進行測試


我有一個使用Spring Roo創建的使用Hibernate和MySQL的Spring項目。然而,對於測試,我想使用HSQLDB在內存中,因爲在Roo集成測試用的ID通過10刪除數據(主鍵)0(而不是使用數據庫分配的ID,因爲他們已經創建數據刪除的數據),這意味着它刪除已經在數據庫中的數據,在我的情況下,它會在回滾事務之前導致違反約束條件。

這是一點點額外的困難,因爲我交換整個數據庫供應商,這意味着不同的Hibernate方言以及不同的DDL設置(驗證生產,創造跌落測試)。但它沒有像我期望的那樣工作,而且我爲什麼不願意工作。

如果你知道爲什麼它不工作,請告訴我,即使你沒有一個解決方案。

這是一個Roo的項目,我當然是使用Maven的。我嘗試了第一件事情是有一個特定的測試src/test/resources/META-INF/persistence.xml文件,同樣是特定的測試src/test/resources/META-INF/spring/database.properties文件。沒有工作,因爲當我跑mvn test一切打破,有關消息是

Conflicting persistence unit definitions for name 'persistenceUnit' 

爲什麼mvn test仍然拿起非測試資源?

於是我改名src/test/resources/META-INF/springspring-test和複製applicationContext.xml進去。我改變了上下文配置在測試類

@ContextConfiguration(locations = "classpath:/META-INF/spring-test/applicationContext*.xml")

完成(或所以我想)的分離,我做了幾個修改的給spring-test/applicationContext.xml

改變了路徑屬性文件:

<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/> 

<context:property-placeholder location="classpath*:META-INF/spring-test/*.properties"/> 

更名持久性單元:

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="persistenceUnit"/> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="testPersistenceUnit"/> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

我取得了持久性單元名稱相應變更src/test/resources/META-INF/persistence.xml

好了,好了,現在有沒有衝突,但不知何故Hibernate已經失去了實體映射(例如,對於Product實體),我得到:

org.springframework.dao.InvalidDataAccessApiUsageException: 
org.hibernate.hql.ast.QuerySyntaxException: Product is not mapped [SELECT o FROM Product o]; 

爲什麼春/休眠此配置中失去了實體映射?

因此,接下來我試着合併兩個persistence.xml文件,以便src/main/resources/META-INF下的一個文件包含兩個持久性單元。

That Works !!?

我覺得這很醜陋,因爲現在我在我的生產代碼中有測試配置,但這正是我所得到的。

什麼是更好的方法?

我的理解是,屬性在persistence.xml中不可用,它們是在Spring XML文件中的方式。所以我不認爲我只需要一個測試特定的屬性文件就可以做我想做的事情。

理想情況下,我會使用src/main/resources下的所有配置來運行測試,除了在src/test/resources中明確覆蓋的配置。 有沒有辦法做到這一點?

感謝您提供的任何見解!

回答

1

在我的工作中,我用來配置沒有數據庫連接信息的persistence.xml。數據庫連接由Spring的上下文配置定義。在Spring框架中,有幾個方法來改變一個對象的屬性:

  1. PropertyPlaceholderConfigurer - 使用不同的屬性文件覆蓋數據庫連接或ORM的方言的價值。如果使用的是resource filter,則可以使用resource filter生成單個屬性文件的不同值。Maven
  2. Bean definition inheritance - 使用另一個上下文配置「覆蓋」默認配置。

下面的代碼是從我的應用程序上下文的摘錄:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" 
    p:location="classpath:frontend.properties" p:ignore-resource-not-found="true" 
    p:systemPropertiesModeName="SYSTEM_PROPERTIES_MODE_OVERRIDE" 
/> 

<util:properties id="jpaProperties"> 
    <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
</util:properties> 

<!-- Global entity manager factory(may not be overrided) --> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:dataSource-ref="dataSource" p:jpaProperties-ref="jpaProperties" 
> 
    <property name="JpaDialect"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 
    </property> 
</bean> 
<!-- :~) --> 

<!-- Data Source --> 
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" 
    p:driverClass="${database.driverClass}" p:jdbcUrl="${database.url}" 
    p:username="${database.username}" p:password="${database.password}" 
    p:partitionCount="${database_conn.pooling.partition_count:2}" 
    p:maxConnectionsPerPartition="64" p:minConnectionsPerPartition="${database_conn.pooling.min_connections:4}" 
    p:acquireIncrement="4" p:statementsCacheSize="64" 
    p:connectionTimeoutInMs="1800000" p:IdleConnectionTestPeriodInMinutes="420" 
/> 
<!-- :~) --> 

下面是測試配置:

<!-- import configuration of application --> 
<import resource="classpath:database.xml" /> 

<!-- 
    - I override some of settings of connection pooling while testing 
    --> 
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" 
    p:driverClass="${database.driverClass}" p:jdbcUrl="${database.url}" 
    p:username="${database.username}" p:password="${database.password}" 
    p:maxConnectionsPerPartition="8" p:minConnectionsPerPartition="2" 
    p:acquireIncrement="2" p:statementsCacheSize="32" 
/> 

當我運行測試,我設置了系統屬性在Maven surefire中配置不同的數據庫。如下例:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.8.1</version> 
    <configuration> 
     <systemPropertyVariables> 
      <!-- Using HSQLDB as test database system --> 
      <database.driverClass>org.hsqldb.jdbc.JDBCDriver</database.driverClass> 
      <database.url>${database.hsqldb.url}</database.url> 
      <database.username>any</database.username> 
      <database.password>any</database.password 
      <hibernate.dialect>org.hibernate.dialect.HSQLDialect</hibernate.dialect> 
      <!-- :~) --> 
     </systemPropertyVariables> 
    </configuration> 
</plugin> 
+0

謝謝,邁克。我也將數據庫信息保存在屬性文件中。我沒有看到的是如何通過屬性更改Hibernate SQL方言,因爲我在persistence.xml中配置了Hibernate。 – 2012-04-12 03:18:44