Hi,

in our application, we frequently (not always) observe TransactionRequiredExceptions on startup:

2020-07-03T05:02:40,261 ERROR - Could not create or update entity in database
javax.persistence.TransactionRequiredException:
Exception Description: No externally managed transaction is currently active for this thread at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:96) ~[!/:?] at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.checkForTransaction(JTATransactionWrapper.java:56) ~[!/:?] at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.registerIfRequired(JTATransactionWrapper.java:133) ~[!/:?] at org.eclipse.persistence.internal.jpa.EntityManagerImpl.joinTransaction(EntityManagerImpl.java:2237) ~[!/:?] at org.apache.aries.jpa.support.impl.XAJpaTemplate.txExpr(XAJpaTemplate.java:60) ~[?:?] at org.apache.aries.jpa.support.impl.AbstractJpaTemplate.txExpr(AbstractJpaTemplate.java:43) ~[?:?]

We are running our application in Karaf 4.2.8, using the features jpa 2.7.2, eclipselink 2.7.5, transaction 2.0 as basis for the persistence layer. Basically, the DAO methods are rather simple: the JpaTemplate service is injected using the respective Declarative Services annotation, and objects are then persisted with

jpaTemplate.tx(entityManager -> entityManager.persist(objectToPersist));

No TransactionType is defined, i.e. the default TransactionType.Required will be used.

When starting the system from the "clean" state, i.e. with the Karaf bundle cache not yet populated, we often - not always - receive the exceptions mentioned above. When such exceptions occur, and Karaf is restarted without deletion of the bundle cache, the exceptions will always reappear. When restarting Karaf with deletion of the bundle cache, sometimes the issue reappears, sometimes it doesn't.

The issue can always be reproduced by restarting the pax-transx-tm-geronimo bundle from the Karaf console. The issue can always be solved by restarting the org.apache.aries.jpa.eclipselink.adapter bundle from the Karaf console.

When investigating further, it could be seen that in the "error state", the XAJpaTemplate in org.apache.aries.jpa.support and the EntityManagerImpl and JTATransactionWrapper in org.eclipse.persistence.jpa hold different instances of the GeronimoTransactionManager (the EntityManagerImpl and JTATransactionWrapper still hold an old instance), while in the "good state", all these classes hold the same instance of the GeronimoTransactionManager. Obviously the org.apache.aries.jpa.eclipselink.adapter bundle doesn't care of changes of the transaction manager. Only when restarting this bundle, the services for EclipseLink are recreated and thus also receive the updated transaction manager. Depending on the startup order of bundles with the same start level (all involved bundles have start level 80), this situation often happens on initial startup. When the start order is fixed such that it results in the "good state", it remains "good" unless the bundle cache is deleted, because the bundle cache fixes the start order. When restarting with "clean", the game starts from scratch.

Now the question: does anybody know a solution for this problem? How can we grant that our application doesn't run into this situation on startup? Or is this something which can only be corrected in the Aries JPA Eclipselink Adapter code?

Thanks & Regards
Jochen

Reply via email to