Craig, thanks for clarifying the spec and David - thanks for the
quick fix. The test in question now works.
Note to Cayenne committers - until the fresh snapshot of
org.apache.geronimo.modules:geronimo-transaction:2.0-SNAPSHOT is
published, you'll need to build and install into local Maven repo
this module to run the integration tests:
http://svn.apache.org/repos/asf/geronimo/server/trunk/modules/
geronimo-transaction/
Andrus
On Feb 5, 2007, at 3:40 AM, David Jencks wrote:
> Thanks for pointing this out. Fixed, see https://issues.apache.org/
> jira/browse/GERONIMO-2795.
>
> When first reading the javadoc I was being a bit too picky and
> decided that "register a synchronization" meant you could only
> register one despite not being able to see how this would work if
> you had more than one jpa provider used in a tx. I see this is the
> same wording that tx.registerSynchronization uses so presumably the
> intent ought to be clear :-)
>
> BTW I continue to be unable to find any jta 1.1 documentation other
> than the javadoc. Has anyone else found an actual spec? I've been
> looking at http://java.sun.com/products/jta/
>
> thanks
> david jencks
>
> On Feb 4, 2007, at 12:11 PM, Craig L Russell wrote:
>
>> Hi Andrus,
>>
>> On Feb 4, 2007, at 8:37 AM, Andrus Adamchik wrote:
>>
>>> 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?
>>
>> The intent of the registerInterposedSynchronization method is to
>> allow any number of callbacks to be registered for synchronization.
>>
>> It's a bug if only one is allowed. There is no requirement for any
>> particular ordering among the callbacks but multiple callbacks are
>> required to be supported.
>>
>> Craig
>>
>>> (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
>>>>
>>>
>>
>> Craig Russell
>> Architect, Sun Java Enterprise System http://java.sun.com/products/
>> jdo
>> 408 276-5638 mailto:Craig.Russel..un.com
>> P.S. A good JDO? O, Gasp!
>>
>
>
This archive was generated by hypermail 2.0.0 : Mon Feb 05 2007 - 06:29:18 EST