I have two persistence.xml
files, for the sake of testing:
src/main/resources/META-INF/persistence.xml
src/test/resources/
Better add both files - in general, making test/production or debug/profile/production distinction in build makes only trouble. Better try to use different perasistence unit name for production (say abc-production) and for tests (abc-tests).
I think you can create two profiles in your pom.xml:
<properties>
<environment>dev</environment>
</properties>
<profiles>
<profile>
<id>prod</id>
<properties>
<environment>test</environment>
</properties>
</profile>
</profiles>
After that, in your src folder, create two folders named dev/resoruces and test/resources and copy your different resources there. After that, add something like this:
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>${basedir}/src/main/${environment}/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
The ${basedir} depends on the command line parameter, it can be test or dev. You run the maven command like this: mvn clean package -P test.
Check out the alternate descriptors functionality which is aimed at what you're trying to do.
Try this setup:
src/main/resources/META-INF/persistence.xml
src/main/resources/META-INF/test.persistence.xml
Then you can construct OpenEJB to prefer the test.persistence.xml
file by setting the openejb.altdd.prefix
System or InitialContext property to test
A different possible solution could be to override the persistence unit properties in the test. With that approach you could avoid the need for a second persistence.xml
which can be nice as maintaining two can be a pain.
You can use the Maven approach, but be aware that per spec the persistence provider will only look (aka scan) for @Entity
beans in the exact jar or directory where the persistence.xml
is found. So be keenly aware that in Maven these are two different locations:
target/classes
target/test-classes
EDIT More details on the overriding capabilities
You can override any property in your test setup via either system properties or the initial context properties (this includes jndi.properties files). The format is:
<unit-name>.<property>=<value>
So for example with the following persistence.xml
:
<persistence>
<persistence-unit name="movie-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>movieDatabase</jta-data-source>
<non-jta-data-source>movieDatabaseUnmanaged</non-jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
You can override and add persistence unit properties in your test case. There are currently no facilities for removing them (if you have a need for that let us know – it hasn't really come up so far).
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
p.put("movie-unit.hibernate.hbm2ddl.auto", "update");
p.put("movie-unit.hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
context = new InitialContext(p);
Or alternatively via a jndi.properties
file
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
movie-unit.hibernate.hbm2ddl.auto = update
movie-unit.hibernate.dialect = org.hibernate.dialect.HSQLDialect
I have been testing these and other similar solutions without involving the pom.xml... In my opinion, the best way to solve this issue is to have two application-context.xml (one only to be used in test classes) and to add a custom persistence unit manager bean in the test's application-context.xml. Like this example:
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocation">
<value>classpath*:META-INF/test.persistence.xml</value>
</property>
<property name="defaultDataSource" ref="dataSource"/>
</bean>
This solution runs. :)