The latest weekly build of geronimo-jetty-j2ee includes support for
jpa. Here are some brief instructions. Note that this does not
include all the nifty jee 5 features such as resource injection and
deployment locating your persitence.xml file for you. However both
container managed and application managed persistence is supported:
there is support for extended persistence contexts but this has not
been tested at all yet.
To deploy a persistence unit, you need a persistence.xml file that
includes all the usual stuff and more specifically the datasources
you wish to use. To specify the datasource include an
AbstractNameQuery sufficient to locate the
ManagedConnectionFactoryWrapper gbean supplying the datasource. Do
not include any interfaces.
For instance, if you deployed your datasource with name jdbc/
TradeDataSource and made sure this was in the ancestors of your app
you would specify
<jta-data-source>?name=jdbc/TradeDataSource</jta-data-source>
Note that if you use openjpa and want a sequence to assign generated
ids you need to also include a non-jta-data-source.
Include the persistence.xml contents directly in your geronimo plan
at the end where gbean definitions go. For instance, for an ejb jar,
you'd put it at the end of openejb-jar.xml like:
...
...
</relationships>
<persistence xmlns="http://java.sun.com/xml/ns/
persistence" version="1.0">
<persistence-unit transaction-type="JTA"
name="daytrader">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</
provider>
<jta-data-source>?name=jdbc/TradeDataSource</jta-
data-source>
<non-jta-data-source>?name=jdbc/
NoTxTradeDataSource</non-jta-data-source>
<class>org.apache.geronimo.samples.daytrader.AccountDataBean</class>
<class>org.apache.geronimo.samples.daytrader.AccountProfileDataBean</
class>
<class>org.apache.geronimo.samples.daytrader.HoldingDataBean</class>
<class>org.apache.geronimo.samples.daytrader.OrderDataBean</class>
<class>org.apache.geronimo.samples.daytrader.QuoteDataBean</class>
<exclude-unlisted-classes/>
<properties>
<property name="openjpa.jdbc.DBDictionary"
value="org.apache.openjpa.jdbc.sql.DerbyDictionary"/>
<property
name="openjpa.jdbc.SynchronizeMappings" value="buildSchema
(ForeignKeys=true)"/>
<property name="openjpa.Sequence"
value="table(Table=OPENJPASEQ, Increment=100)"/>
</properties>
</persistence-unit>
</persistence>
</openejb-jar>
In the environment/dependencies element you need to include your jpa
provider as a dependency. We've packaged up the openjpa jar and its
dependencies into a configuration so you can just add:
<dependency>
<groupId>org.apache.geronimo.configs</groupId>
<artifactId>openjpa</artifactId>
<type>car</type>
</dependency>
and you won't have to track down the right serp version etc.
So now if you deploy your app the persistence unit will get deployed
and started for you.... but you might want to use it in your
application.
We aren't processing jee 5 deployment descriptors or the equivalent
annotations so you have to use geronimo specific xml in your plan.
Here's an example for a container managed persistence context
accessed from a session bean:
<session>
<ejb-name>TradeJPA</ejb-name>
<persistence-context-ref>
<persistence-context-ref-name>jpa/daytrader</
persistence-context-ref-name>
<persistence-unit-name>daytrader</
persistence-unit-name>
<persistence-context-type>transaction-
scoped</persistence-context-type>
</persistence-context-ref>
</session>
from an openejb-jar.xml.
Now your session bean can get the transaction-scoped container
managed EntityManager like this:
public void setSessionContext(SessionContext sc) {
context = sc;
if (sc != null) {
try {
entityManager = (EntityManager) new InitialContext
().lookup("java:comp/env/jpa/daytrader");
} catch (NamingException e) {
throw new EJBException("could not get Naming Context", e);
}
} else {
entityManager = null;
}
}
If for some reason you want to use application managed persistence
contexts you'd include something like this in your plan:
<session>
<ejb-name>TestSession</ejb-name>
<entity-manager-factory-ref>
<entity-manager-factory-ref-name>jpa/testEMF</entity-
manager-factory-ref-name>
<persistence-unit-name>test-unit</persistence-unit-
name>
</entity-manager-factory-ref>
</session>
Looking up the EntityManagerFactory looks like this:
EntityManagerFactory entityManagerFactory =
(EntityManagerFactory) new InitialContext().lookup("java:comp/env/jpa/
testEMF");
Given some public outcry we could make the xml tag names more similar
by changing persistence-context to entity-manager in the first style
of xml.
-------------------------------
enhancement
I recommend you pre-enhance your classes as you build your app. If
you use maven 2 there are some examples of how to do it in the
samples mentioned below.
If you wish to live dangerously and use runtime enhancement, that
works too, sometimes. The current limitation is that no gbean datas
can include classes or objects of classes that need to be enhanced,
since the gbean datas are deserialized before the bytecode
transformer is installed. One way you can get into trouble with this
is if a web service endpoint uses jpa persistence-capable data beans
as method arguments.
In order to get runtime enhancement you need to start the server with
our jpa agent with a command line like this:
java -javaagent:bin/jpa.jar -jar bin/server.jar
This works with the simple test app but not with daytrader due to the
web service problem just mentioned.
---------------------------------
So far there are the following examples:
-- a very simple test app that requires you to build the sandbox/
javaee5 stuff and run the geronimo-jetty6-jee5 server. It's located
in sandbox/javaee5/itests/jpa.
-- daytrader trunk. This is converted so jpa is an option. Deploy
with the plan daytrader-jpa-plan.xml in daytrader/trunk/plans. After
you deploy daytrader you need to first visit the configuration page
and set the persistence method to JPA. Then populate the database
and start trading. I don't know if the old direct and ejb
persistence methods still work: in particular I'm pretty sure the id
generation methods are incompatible so if you want to try changing
persistence method, clear the data and repopulate.
Try it out and please report problems
thanks
david jencks