Hi Dain,
Just got some time to write a JPA/OpenEJB integration test following
your example. Everything works except for one thing. Here is my
sample code:
GeronimoTransactionManagerJTA11 tm = new
GeronimoTransactionManagerJTA11();
System.setProperty(
Context.INITIAL_CONTEXT_FACTORY,
LocalInitialContextFactory.class.getName());
new InitialContext().bind("java:comp/
TransactionSynchronizationRegistry", tm);
EntityManagerFactory factory = ... // init code for Cayenne
JTA EMF
JtaEntityManagerRegistry registry = new
JtaEntityManagerRegistry(tm);
tm.begin();
EntityManager entityManager = new JtaEntityManager(
registry,
factory,
new Properties(),
false);
SimpleEntity e = new SimpleEntity();
e.setProperty1("XXX");
entityManager.persist(e);
tm.commit(); // Nothing is saved to the DB here
Now the problem...
According to the JPA spec, ch. 5.9.2, "When
EntityManagerFactory.createEntityManager is invoked, the provider
must create and return a new entity manager. If a JTA transaction is
active, the provider must register for synchronization notifications
against the JTA transaction."
So that's what Cayenne EMF does [1], [2] via
TransactionSynchronizationRegistry.registerInterposedSynchronization
(..). At a later time OpenEJB JtaEntityManager calls the same method
on the registry to register a its own close operation, kicking out
Cayenne EM callback. The end result is that the EntityManager is not
flushed in "beforeCompletion" and nothing is saved to DB.
I suspect Geronimo TransactionImpl is to blame here. It only allows a
single interposed synchronization. Is it a requirement of the JTA
spec? (if it is, I couldn't find any mention of it). If everyone
agrees with my assessment of the situation, I can submit a patch.
Thoughts?
Andrus
[1] https://svn.apache.org/repos/asf/cayenne/main/trunk/framework/
cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/
JtaEntityManagerFactory.java
[2] https://svn.apache.org/repos/asf/cayenne/main/trunk/framework/
cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/
JtaEntityManager.java
On Jan 11, 2007, at 10:34 PM, Dain Sundstrom wrote:
> I just committed the JtaEntityManager and JtaEntityManagerRegistry
> to the openejb-persistence module. You can create a
> JtaEntityManager with the following code:
>
> JtaEntityManagerRegistry registry = new JtaEntityManagerRegistry
> (transactionSynchronizationRegistry);
> EntityManager entityManager = new JtaEntityManager(registry,
> entityManagerFactory,
> properties,
> extended);
>
> That's it. The under the covers of the JtaEntityManager a new
> EntityManager instance is created using the EMF for each transaction.
>
> A single instance of the JtaEntityManagerRegistry should be shared
> by all JtaEntityManagers. TransactionSynchronization registry is a
> new interface in JTA 1.1. The Geronimo JTA 1.1 transaction manager
> implements this interface directly, but if you are not using that
> transaction manager just wrap your transaction manager with the
> openejb SimpleTransactionSynchronizationRegistry.
>
> If you want to test extended entity managers (only used by stateful
> session beans), you will need to simulate stateful session bean
> construction, entrance, exit and starting of user transactions by
> call in the appropriate method on the JtaEntityManagerRegistry.
>
> If you run into problems, don't hesitate to ask.
>
> -dain
>
This archive was generated by hypermail 2.0.0 : Sun Feb 04 2007 - 11:38:37 EST