I am working on a project that uses JPA/HIbernate and Spring for persistence and transaction management. This application has tables mapped from several catalogs and schemas from the same database server (a Sybase environment).
In order to start creating automated tests for this app using an in-memory database, I had to create an alternative test-persistence.xml
listing all the same entities from the default persistence.xml
, but specifying alternative orm.xml
mapping files that override the schema information from the annotations in the classes.
The critical piece in my Spring configuration for tests is like this:
<bean id="hsqlFixes" class="com.example.app.util.HSQLFixes" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="hsqlFixes">
<property name="persistenceUnitName" value="puName" />
<property name="persistenceXmlLocation"
value="META-INF/persistence-tests.xml" />
....
</bean>
Where HSQLFixes
is a bean that executes some JDBC statements just creating some types.
And in the persistence-tests.xml
:
<persistence-unit name="puName" transaction-type="RESOURCE_LOCAL">
<mapping-file>META-INF/orm-tests-db1.xml</mapping-file>
<mapping-file>META-INF/orm-tests-db2.xml</mapping-file>
<mapping-file>META-INF/orm-tests-db3.xml</mapping-file>
... followed by the same list of entities from persistence.xml
Now, I want to get rid of the duplication of the classes listing in persistence.xml
and test-persistence.xml
, cause I feel I could automate the generation of this second file.
How could I go to do it dynamically, so that I don't need to change both XML files when I add/remove an entity?
I would suggest configuring your test persistence unit programmatically to avoid multiple persistence.xml's or multiple persistence units. This case is made a bit more complicated by the multiple schemas requirement as it involves mapping file overrides. Standard properties are easy to pass in when creating an EntityManagerFactory, but this case would require the use of a PersistenceUnitPostProcessor using the MutablePersistenceUnitInfo to add the mapping file references.
Take a look at Programmatically loading Entity classes with JPA 2.0? for a good example of how you would configure this. The API on MutablePersistenceUnitInfo will allow you to add the mapping file refs. As for the class refs, you would be getting this automatically from the original persistence.xml which you are modifying in the post processing (in the test config only), which solves the duplication problem.
So, maybe you could end up with a PersistenceUnitPostProcessor like this:
public class ConfigureTestMappingFiles implements PersistenceUnitPostProcessor {
private List<String> mappingFiles;
@Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
if (mappingFiles != null) {
pui.getMappingFileNames().addAll(mappingFiles);
}
}
// ... getter and setter for mappingFiles
}
and, in your configuration you would register it like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="hsqlFixes">
<property name="persistenceUnitName" value="programasPlanosEnsino" />
<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
...
<property name="persistenceUnitPostProcessors">
<list>
<bean class="com.example.test.ConfigureTestMappingFiles">
<property name="mappingFiles">
<list>
<value>META-INF/orm-tests-db1.xml</value>
<value>META-INF/orm-tests-db2.xml</value>
... add more as needed
</list>
</property>
</bean>
</list>
</property>
Hope this helps.