2012-03-28 34 views
6

OK, xin lỗi, tôi đã tìm câu trả lời cho điều này trong nhiều giờ, nhưng tôi đã nhập toàn bộ câu hỏi cho StackOverflow để bong bóng lên liên kết tôi đang tìm kiếm. Bạn có thể đọc rất nhiều thông tin liên quan here.Sử dụng tệp persistence.xml riêng biệt để sản xuất và thử nghiệm với Spring 3.1


Tôi có một dự án Spring được tạo bằng Spring Roo để sử dụng Hibernate và MySQL. Tuy nhiên, để thử nghiệm, tôi muốn sử dụng HSQLDB trong bộ nhớ vì các thử nghiệm tích hợp Roo xóa dữ liệu với các ID (các khóa chính) từ 0 đến 10 (thay vì xóa dữ liệu bằng cách sử dụng các id được chỉ định cho dữ liệu mà chúng đã tạo), có nghĩa là nó xóa dữ liệu đã có trong cơ sở dữ liệu, mà trong trường hợp của tôi gây ra một sự vi phạm ràng buộc trước khi nó được xung quanh để quay trở lại giao dịch. Đây là một chút khó khăn hơn bởi vì tôi đang chuyển đổi toàn bộ các nhà cung cấp cơ sở dữ liệu có nghĩa là các phương ngữ Hibernate khác nhau cũng như các thiết lập DDL khác nhau (xác thực trong sản xuất, tạo thả trong thử nghiệm). Nhưng nó không hoạt động như tôi mong đợi và tôi đang bối rối là tại sao.

Nếu bạn biết tại sao nó không hoạt động, hãy nói như vậy, ngay cả khi bạn không có giải pháp.

Đây là dự án Roo, tôi đang sử dụng Maven. Vì vậy, điều đầu tiên tôi đã thử đã có một tập tin cụ thể kiểm tra src/test/resources/META-INF/persistence.xml và tương tự như một tập tin kiểm tra cụ thể src/test/resources/META-INF/spring/database.properties. Mà không làm việc, như khi tôi chạy mvn test tất cả mọi thứ đã phá vỡ, với thông điệp có liên quan là

Conflicting persistence unit definitions for name 'persistenceUnit' 

Tại sao mvn test vẫn chọn lên các nguồn tài nguyên không kiểm tra?

Vì vậy, sau đó tôi đổi tên thành src/test/resources/META-INF/spring thành spring-test và sao chép applicationContext.xml vào trong đó. Tôi đã thay đổi cấu hình ngữ cảnh trong các lớp học thử nghiệm để

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

Hoàn (hoặc vì vậy tôi nghĩ) sự tách biệt, tôi đã thực hiện một vài chỉnh sửa để spring-test/applicationContext.xml:

thay đổi con đường cho các tập tin thuộc tính:

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

để

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

Thay đổi tên của đơn vị bền vững:

<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> 

Và tôi thực hiện thay đổi tương ứng trong tên đơn vị kiên trì để src/test/resources/META-INF/persistence.xml

Vâng, OK, bây giờ không có xung đột, nhưng bằng cách nào đó Hibernate đã mất ánh xạ thực thể (ví dụ cho đơn vị Product) và tôi nhận được:

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

Tại sao mùa xuân/Hibernate bị mất ánh xạ thực thể trong cấu hình này?

Vì vậy, điều tiếp theo tôi đã thử là hợp nhất hai tệp persistence.xml để một tệp dưới src/main/resources/META-INF bao gồm cả hai đơn vị lưu giữ lâu dài.

Tác phẩm đó !! ??

Tôi nghĩ nó xấu xí, bởi vì bây giờ tôi có cấu hình thử nghiệm trong mã sản xuất của mình, nhưng đó là những gì tôi nhận được.

Cách nào tốt hơn?

Tôi hiểu rằng các thuộc tính không có sẵn bên trong persistence.xml theo cách chúng ở bên trong tệp Spring XML. Vì vậy, tôi không nghĩ rằng tôi có thể làm những gì tôi muốn chỉ với một tập tin đặc tính thử nghiệm cụ thể.

Lý tưởng nhất là tôi chạy thử nghiệm bằng cách sử dụng tất cả cấu hình trong src/main/resources ngoại trừ những gì được ghi đè cụ thể trong src/test/resources. Có cách nào để thực hiện việc này không?

Cảm ơn bạn đã có bất kỳ thông tin chi tiết nào mà bạn có thể cung cấp!

Trả lời

1

Trong công việc của mình, tôi đã sử dụng để định cấu hình persistence.xml mà không có thông tin về kết nối cơ sở dữ liệu. Kết nối cơ sở dữ liệu được định nghĩa bởi cấu hình ngữ cảnh của Spring. Trong khung công tác Spring, có một số cách để thay đổi các thuộc tính của một đối tượng:

  1. PropertyPlaceholderConfigurer - Sử dụng tệp thuộc tính khác để ghi đè giá trị của kết nối cơ sở dữ liệu hoặc phương ngữ ORM. Bạn có thể sử dụng resource filter để tạo các giá trị khác nhau của một tệp thuộc tính nếu bạn đang sử dụng Maven
  2. Bean definition inheritance - Sử dụng cấu hình ngữ cảnh khác để "ghi đè" cấu hình mặc định.

Tiếp theo mã là một đoạn trích từ bối cảnh của tôi về ứng dụng:

<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" 
/> 
<!-- :~) --> 

Dưới đây là cấu hình để thử nghiệm:

<!-- 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" 
/> 

Khi tôi đang chạy thử nghiệm, tôi thiết lập các thuộc tính hệ thống trong Maven surefire để định cấu hình cơ sở dữ liệu khác. Như mẫu sau:

<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

Cảm ơn, Mike. Tôi giữ thông tin cơ sở dữ liệu trong một tập tin thuộc tính, quá. Những gì tôi không thấy là làm thế nào để thay đổi phương ngữ Hibernate SQL thông qua các thuộc tính, như tôi cấu hình Hibernate trong persistence.xml. –

Các vấn đề liên quan