OpenJPA - Transaction management is not available… (Fuse ESB)

你离开我真会死。 提交于 2019-12-21 20:39:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!