users@glassfish.java.net

Re: embedded ejb container - JTA and entity managers

From: Phillip Ross <phillip.w.g.ross_at_gmail.com>
Date: Thu, 3 Mar 2011 17:25:57 -0500

No go doing the creation of emf or em inside the transaction either. I get
no errors, but the data never actually gets committed to the database
either. I also tried starting the transaction, creating the emf/em and
calling joinTransaction on the em... but I get the same "no active
transaction" exception in both cases.

I do remember being surprised that Persistence created an emf and em that
were jta enabled and aware of the glassfish embedded transaction manager
when I was working with the test code in 3.0.1, as I used to test outside of
the container with atomikos transaction essentials. When using atomikos I
had to write a custom transaction controller that was configured in an
eclipselink session initializer and included in the persistence.xml. This
required me to maintain two separate persistence.xml files since the
datasources were completely different. When I ported the code to 3.0.1
embedded container it was a pleasant surprise to see Persistence returning
emf/ems that were integrated in with the glassfish JTA impl and it all just
worked with user managed transactions as long as I included the code to have
the entity manager join the transaction everytime there was a new user
transaction started.

So, as another expirement I added some code to grab a JPA local transaction
object and start a local transaction, but that doesnt work either. No
exceptions are thrown, but the data is never committed. I'm assuming this
happens because the persistence unit is configured to use JTA rather than
local transactions.

At this point, I'm wondering, what changed between 3.0.1 and 3.1 that would
make this not work? Maybe an assumption that Persistence would not be used
to get a JTA aware persistence context and code changes for whatever code
exists in glassfish to incorporate JPA providers? I'm personally hoping
it's a bug that can be fixed rather than explicit coding to force
Persistence to return non-JTA aware emf/fm instances!

On Thu, Mar 3, 2011 at 3:08 PM, Marina Vatkina <marina.vatkina_at_oracle.com>wrote:

> Philip,
>
> Try looking up EMF (or EM inside an active transaction, and you won't need
> to join it). Persistence.createEntityManagerFactory() usually creates a
> non-JTA EMF.
>
> -marina
>
> Phillip Ross wrote:
>
>> Here's an inline, slightly abbreviated version of my persistence.xml
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <persistence xmlns="http://java.sun.com/xml/ns/persistence"
>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
>> version="2.0">
>>
>> <persistence-unit name="default" transaction-type="JTA">
>>
>> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
>> <jta-data-source>jdbc/test_ds</jta-data-source>
>> <class>TestEntity</class>
>> <properties>
>> <property name="eclipselink.logging.level" value="SEVERE"/>
>> </properties>
>> </persistence-unit>
>> </persistence>
>>
>> The real one has a different datasource name and lots more, real class
>> names, but this one illustrates the pu name and tx type I'm attempting to
>> use.
>>
>> Another interesting datapoint, I added some code to interrogate the entity
>> manager and it seems to not know the server platform or claim to support
>> JTA. Code looks like this:
>> Object entityManagerDelegateObject = entityManager.getDelegate();
>> logger.debug("Retrieved a delegate object of type {}",
>> entityManagerDelegateObject.getClass().getName());
>> if (entityManagerDelegateObject instanceof EntityManagerImpl) {
>> EntityManagerImpl entityManagerImpl =
>> (EntityManagerImpl)entityManager.getDelegate();
>> Session session = entityManagerImpl.getSession();
>> ServerPlatform serverPlatform = session.getServerPlatform();
>> logger.debug("server platform: {}",
>> serverPlatform.getServerNameAndVersion());
>> logger.debug("jta enabled: {}", serverPlatform.isJTAEnabled());
>> }
>>
>> And the output from this looks like this:
>> - Retrieved a delegate object of type
>> org.eclipse.persistence.internal.jpa.EntityManagerImpl
>> - server platform: null
>> - jta enabled: false
>>
>> But placing the same code inside a stateless EJB produces this output:
>> - server platform: unknown
>> - jta enabled: true
>>
>> I dont really know if this has anything to do with anything, but thought
>> it was interesting.
>>
>>
>> On Thu, Mar 3, 2011 at 1:33 PM, Mitesh Meswani <mitesh.meswani_at_oracle.com<mailto:
>> mitesh.meswani_at_oracle.com>> wrote:
>>
>> On 3/3/2011 10:30 AM, Phillip Ross wrote:
>>
>> at
>>
>> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper.checkForTransaction(EntityTransactionWrapper.java:50)
>>
>> Use of EntityTransactionWrapper implies that you are not using a
>> JTA pu. Check your persistence.xml to make sure that it is a JTA pu.
>>
>> -Mitesh
>>
>> at
>>
>> org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:1666)
>>
>>
>>
>>