I second Jean-Louis' recommendation to use just one unit.
One additional approach is that nearly all aspects of the persistence-
unit can be overridden by OpenEJB.
1. The <jta-data-source> and <non-jta-data-source>
We will automatically use the datasources you have setup in your test
environment, we're pretty good at guessing the right datasources you
intend. A log line will be printed saying if we had to adjust your
persistence.xml.
2. The unit <properties>
You can override any property in your test setup via either system
properties or the initial context properties. The format is:
<unit-name>.<property>=<value>
So for example:
Properties p = new Properties();
p
.put
(Context
.INITIAL_CONTEXT_FACTORY
,"org.apache.openejb.client.LocalInitialContextFactory");
p.put("exampleDatabase", "new://Resource?type=DataSource");
p.put("exampleDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("exampleDatabase.JdbcUrl", "jdbc:hsqldb:mem:exampledb");
// Note, if you don't configure an unmanaged datasource, we
will
// automatically create one for you based on the above
datasource.
// here we're setting an persistence unit property
p.put("myUnit.hibernate.hbm2ddl.auto", "update");
context = new InitialContext(p);
3. Special note on "hibernate.transaction.manager_lookup_class"
Nothing works if this is not set correctly to the OpenEJB specific
class, so we take the liberty of setting it for you. There's no need
to set it yourself.
An note on the altdd support: we actually added this only recently on
purpose after a bit of hesitation. Reason being is that the most
common cases of wanting things to be "different" are taken care of
automatically. The boring "need to use a different" database kind of
needs are covered. It's really only when you are trying to do
something really complicated that you need to break into the altdd
support.
Think we need to update the altdd page with a big disclaimer that
there is an easier way to do persistence unit configuration.
-David
On Aug 18, 2009, at 1:06 PM, Jean-Louis MONTEIRO wrote:
Hi Adrian,
Using two persistence units seems not appropriated. Moreover,
defining those
persistence units in two different persistence.xml files can be
error prone.
Regarding maven, src/main/java + src/main/resources will go to
target/classes so it will be deployed as an ejb module.
src/test/java + src/test/resources will go two a different module in
target/test-classes
I can see two solutions to solve your problem (from my understanding).
For both, i recommend not to use two persistence units. You only
need one
persistence unit, but you need to change the data source for tests,
production, ...
1. the first is using maven: you can define a persistence.xml
(src/main/filters) with strings you can dynamically change using
filters.
for example: <jta-data-source>@target.datasource@</jta-data-source>
Then, you just need to create two profiles:
- test (for example) activated by default used to change the
datasource to
the test one.
- production (for example) used during packaging/deply phase or any
other by
using the -P switch.
Everything is well described in the maven definitive user guide.
2. using alternate deployment descriptors
You can use 2 persistence.xml file defining the same persistence
unit (one
for test and the other for production). Then, you just have to set the
system property (altdd) to switch from one to the other.
Hope it helps.
Jean-Louis
burriad wrote:
<Second try, full problem description this time around...>
Hi,
I'm facing the following issue: I have to DB instances, one for
testing
(an in-memory HSQLDB database) and one for production (will be
MySQL ,
for now I use exactly the same DB). To make the switch between the
two,
I came up with the following setup:
1. Maven project, with OpenEJB registered for testing (I won't show
the pom here)
2. One persistence.xml with two persistence units (I tried to put
one persistence.xml in /src/test/resources, but it didn't got
recognized
during testing) .
<persistence-unit name="ejb-example-openejb">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>exampleDatabase</jta-data-source>
<non-jta-data-source>exampleDatabaseUnmanaged</non-jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property
name="hibernate.transaction.manager_lookup_class"
value="org.apache.openejb.hibernate.TransactionManagerLookup"/>
</properties>
</persistence-unit>
<persistence-unit name="ejb-example-openejb-testing">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>exampleDatabase</jta-data-source>
<non-jta-data-source>exampleDatabaseUnmanaged</non-jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property
name="hibernate.transaction.manager_lookup_class"
value="org.apache.openejb.hibernate.TransactionManagerLookup"/>
</properties>
</persistence-unit>
3. A test case setup with the altdd-Option activated:
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
p.put("openejb.altdd.prefix", "test");
p.put("exampleDatabase", "new://Resource?type=DataSource");
p.put("exampleDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("exampleDatabase.JdbcUrl", "jdbc:hsqldb:mem:exampledb");
p.put("exampleDatabaseUnmanaged",
"new://Resource?type=DataSource");
p.put("exampleDatabaseUnmanaged.JdbcDriver",
"org.hsqldb.jdbcDriver");
p.put("exampleDatabaseUnmanaged.JdbcUrl",
"jdbc:hsqldb:mem:exampledb");
p.put("exampleDatabaseUnmanaged.JtaManaged", "false");
context = new InitialContext(p);
4. An ejb-jar.xml and a test.ejb-jar.xml that look almost the same,
besides pointing to a different persistence unit (only test.ejb-
jar.xml
shown here):
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>SessionFacadeImpl</ejb-name>
<persistence-context-ref>
<persistence-context-ref-name>persistenceContext</persistence-
context-re
f-name>
<persistence-unit-name>ejb-example-openejb-testing</persistence-
unit-nam
e>
</persistence-context-ref>
</session>
</enterprise-beans>
</ejb-jar>
5. As you might have guessed, my stateless session bean looks like
follows:
@Stateless
public class SessionFacadeImpl implements SessionFacadeLocal {
@PersistenceContext(name="persistenceContext")
private EntityManager em;
...
}
Now I get an error when I run the tests. The error message looks like
follows:
ERROR - FAIL ... null: The persistence unit "" does not exist.
Update
the "persistenceContext" PersistenceContext ref to one of the
available
units [ejb-example-openejb-testing, ejb-example-openejb] or declare
the
unit in a persistence.xml like the following:<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0"><persistence-unit
name=""><jta-data-source>java:openejb/Resource/myDataSource</jta-
data-so
urce><non-jta-data-source>java:openejb/Resource/
myUnmanagedDataSource</n
on-jta-data-source><properties><property
name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(ForeignKeys=true)"/></properties></persistence-
unit><
/persistence>
If I do as I am told an add this empty persistence unit, I will get
an
error like this:
ERROR - FAIL ... null: The reference
@PersistenceContext(name="persistenceContext", unitName="") cannot be
resolved as there are 3 units with the same name. Update your
unitName
to one of the following: 390766514
SeminarEntityManager 390766514
ejb-example-openejb 390766514
So, what is wrong here? Is the configuration wrong, or is it a
problem
with OpenEJB? Or am I down the wrong path with my setup and there's
an
easier way to have a separate DB instance for testing.
Any help would be appreciated. I could narrow the problem to the
point
that I could see that putting a second persistence unit into
persistence.xml caused the problem, so the ejb-jar.xml
configuration on
a single persistence unit works as outlined.
Adrian Burri
Software Engineering
--
View this message in context:
http://www.nabble.com/Multiple-Persistence-Units-tp25027340p25032565.html
Sent from the OpenEJB User mailing list archive at Nabble.com.