Using separate persistence.xml files for production and testing with Spring 3.1

OK, sorry, I have been looking for answers to this for several hours, but I needed to enter the whole question so that StackOverflow would launch the link I was looking for. Here you can read a lot of important information.


I have a Spring project created using Spring Roo to use Hibernate and MySQL. However, for testing, I want to use HSQLDB in memory, because Roo integration tests delete data with identifiers (primary keys) from 0 to 10 (instead of deleting data using the assigned database identifiers for the data that they have already created), which means deletes data that is already in the database, which in my case causes a violation of the restriction before it turns around to cancel the transaction.

This is a bit more complicated, because I switch entire database providers, which means different dialects of hibernation, as well as different DDL settings (validation in production, creation-fall in the test). But it does not work, as I expect, and I am at a standstill why.

If you know why it does not work, say so, even if you do not have a solution.

This is a Roo project, I am using Maven, of course. So, the first thing I tried was the test file src/test/resources/META-INF/persistence.xml , as well as the test file src/test/resources/META-INF/spring/database.properties . This did not work, because when mvn test started, everything broke, and the corresponding message was

 Conflicting persistence unit definitions for name 'persistenceUnit' 

Why was mvn test still collecting non-test resources?

So, I renamed src/test/resources/META-INF/spring to spring-test and copied applicationContext.xml into it. I changed the context configuration in the test classes to

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

Having completed (or so I thought) the separation, I made a couple of corrections to spring-test/applicationContext.xml :

The path to the property files has been changed:

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

to

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

Changed unit name:

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

to

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

And I made a corresponding change in the name of the save unit to src/test/resources/META-INF/persistence.xml

Well, well, now there is no conflict, but for some reason Hibernate has lost entity mappings (for example, for the Product object), and I get:

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

Why has Spring / Hibernate lost object mappings in this configuration?

So, I tried to merge two persistence.xml files so that one file in src/main/resources/META-INF included as a unit of conservation.

What works!!??

I think this is ugly, because now I have a test configuration in my production code, but this is what I get with.

What's better?

As far as I understand, the properties in the persistence.xml file are not available, as they are inside the Spring XML files. Therefore, I don’t think I can do what I want with just a test properties file.

Ideally, I would run tests using the entire configuration in src / main / resources, except that it is specifically overridden in src / test / resources. Is there any way to do this?

Thanks for any information you can provide!

+6
source share
1 answer

In my work, I used the persistence.xml setting without information about connecting to the database. The database connection is determined by the Spring context configuration. In the Spring structure, there are several ways to change the properties of an object:

The following code is an excerpt from my application context:

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

Here is the configuration for testing:

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

When I run the test, I configure the system properties in Maven surefire to configure another database. As below:

 <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> 
+1
source

Source: https://habr.com/ru/post/911906/


All Articles