Question

I'm having trouble with RESOURCE_LOCAL transaction type for JPA in Fuse ESB.

I also don't have a complete understanding of whether JTA or RESOURCE_LOCAL is better for me.

My persistence.xml :

<persistence-unit name="invoicePersistence" transaction-type="RESOURCE_LOCAL">

    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/invDataSource)</jta-data-source>
    <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/invDataSource)</non-jta-data-source>
    <class>com.company.service.Invoice</class>
    <!-- etc... -->

</persistence-unit>

My beans in blueprint.xml :

<reference id="invDataSource" interface="javax.sql.DataSource" filter="(datasource.name=invDataSource)"/>

<bean id="invoiceDao" class="com.company.project.InvoiceDao">
    <jpa:context unitname="invoicePersistence" property="entityManager"/>
    <tx:transaction method="*" value="Required" />
</bean>

And my code :

    entityManager.getTransaction().begin();

    entityManager.persist(a);
    entityManager.persist(b);

    entityManager.getTransaction().commit();

And the exception, using transaction-type RESOURCE_LOCAL in my persistence.xml:

java.lang.IllegalStateException: Transaction management is not available for container managed EntityManagers.

I also tried using transaction-type JTA in my persistence.xml but then I received OptimisticLockException.

I'm not sure which approach is better (RESOURCE_LOCAL or JTA) but the main thing is that in my code object a and b need to be persisted in a transaction (all or nothing).

I'm running in Fuse ESB (camel, cxf, etc).

Thanks for any tips or help.

Was it helpful?

Solution

Ok, here is the answer.

Firstly, 2 nice links on JPA Concepts and the Aries JPA Container

RESOURCE_LOCAL

transaction-type="RESOURCE_LOCAL" is indeed self-managed persistence, and the code should be like this:

EntityManager entityManager = entityManagerFactory.createEntityManager();

...

entityManager.getTransaction().begin();
entityManager.persist(a);
entityManager.persist(b);
entityManager.getTransaction().commit();

Using entityManager.getTransaction() and entityManager.flush() both caused exceptions, because I had specified <jpa:context>.

The correct way to do it is with <jpa:unit> and EntityManagerFactory.

<bean id="invoiceDao" class="com.company.project.InvoiceDao">
    <jpa:unit unitname="invoicePersistence" property="entityManagerFactory"/>
</bean>

JTA

On the other hand transaction-type="JTA" is 'container-managed' persistence:

entityManager.persist(a);
entityManager.persist(b);

and it should be configured in blueprint with <jpa:context> and an EntityManager.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top