Re: JPA events for cmp and JPA testing

From: David Jencks (david_jenck..ahoo.com)
Date: Sun Feb 04 2007 - 20:40:46 EST

  • Next message: sankara rao bhogi: "Re: JPA events for cmp and JPA testing"

    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 - 05:49:02 EST