问题
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.
回答1:
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
.
来源:https://stackoverflow.com/questions/17487174/openjpa-transaction-management-is-not-available-fuse-esb