Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to instruct Maven to ignore my main/resources/persistence.xml in favor of test/...?

I have two persistence.xml files, for the sake of testing:

  • src/main/resources/META-INF/persistence.xml
  • src/test/resources/META-INF/persistence.xml

How to instruct Maven to ignore the first file during testing? Now it is not ignored since OpenEJB says:

ERROR - FAIL ... Finder: @PersistenceContext unitName has multiple matches: 
unitName "abc" has 2 possible matches.
like image 769
yegor256 Avatar asked Oct 05 '10 10:10

yegor256


People also ask

Can we have multiple persistence xml?

The Java Persistence API allows you to define multiple persistence units, each of which can map to a separate database.

What is the purpose of the persistence XML file?

The persistence. xml configuration file is used to configure a given JPA Persistence Unit. The Persistence Unit defines all the metadata required to bootstrap an EntityManagerFactory , like entity mappings, data source, and transaction settings, as well as JPA provider configuration properties.

How do I edit persistence xml?

In the Package Explorer view, right-click the persistence. xml file of the JPA project that you want to edit and select Open with > Persistence XML Editor. In the Design tab of the Persistence XML Editor, make any of the following changes to the persistence.

Where should persistence xml be located?

If you package the persistence unit as a set of classes in a WAR file, persistence. xml should be located in the WAR file's WEB-INF/classes/META-INF directory.


2 Answers

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
like image 143
David Blevins Avatar answered Oct 19 '22 18:10

David Blevins


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.

like image 39
virgium03 Avatar answered Oct 19 '22 17:10

virgium03