Quarkus: Cannot use multiple persistence units in same transaction

Created on 19 Oct 2020  路  11Comments  路  Source: quarkusio/quarkus

Describe the bug
Given two Java packages configured in two separate persistence units, it is not possible to query entities in both of them within the same transaction. The query for the second persistence unit will always fail, while the first one works (i.e. no matter which PU is queried first, the other will fail). Querying the PUs outside of a transaction succeeds, though.

Expected behavior
It should be possible to query two different persistence units within the same transaction.

Actual behavior
The second query always fails with java.lang.IllegalArgumentException: Could not locate ordinal parameter [1], expecting one of []

To Reproduce
panache-multipe-persistence-units.zip
Steps to reproduce the behavior:

  1. unzip above archive (code is based on hibernate-orm-panache-quickstart)
  2. invoke mvn test
  3. see test class fail in org.acme.hibernate.orm.panache.MultiPersistenceUnitTest.testBothQueriesInTx(), while tests doing the same outside of a transaction succeed

Environment (please complete the following information):

  • Output of uname -a or ver: Darwin C02Z74E4LVDQ 19.6.0 Darwin Kernel Version 19.6.0: Thu Jun 18 20:49:00 PDT 2020; root:xnu-6153.141.1~1/RELEASE_X86_64 x86_64
  • Output of java -version: OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.4+11, mixed mode)
  • GraalVM version (if different from Java):
  • Quarkus version or git rev: 1.8.3-Final
  • Build tool (ie. output of mvnw --version or gradlew --version): Apache Maven 3.6.3
arepersistence kinbug

All 11 comments

I have the same problem in my project锛孈Sanne

13:30:19 WARN  [or.hi.hq.in.QuerySplitter] (executor-thread-198) HHH000183: no persistent classes found for query class: FROM org.whedu.resource.plane.Plane

It seems that io.quarkus.hibernate.orm.runtime.entitymanager.TransactionScopedEntityManager (TSEM) uses the following as the key for registering a "real" EntityManager with the current thread's transaction:

private static final Object transactionKey = new Object();

As the TSEM itself has the name of the persistence unit as a constructor argument, the TSEM seems to be meant only for a single persistence unit. But the key above is a static object (one per class), so all TSEMs in the transaction will overwrite each other's EntityManagers in the transaction, or rather, assume another TSEM's EM to be theirs. That could explain why the wrong EntityManager is applied for a query in the transaction.

I guess the key must not be a static object, but should be something like TransactionScopedEntityManager.class.getName() + unit, so there will be one EntityManager per unit registered in the transaction.

Can reproduce the bug with 1.9.0.Final as well, using above example project.

Yeah, you're right, there's something fishy.

Let me clean this up.

OK I was able to fix it using a key for the transaction as described above. Will try to provide a Merge-Request.

Looks like accessing two PUs in one transaction wasn't covered by a test yet? io.quarkus.hibernate.orm.multiplepersistenceunits.MultiplePersistenceResourceInjectionUnitsTest looks like the right place for it, but didn't cover it so far?

@jfrantzius if it wasn't clear, I'm working on it (mostly because I wanted to do other cleanup in the file)

I was a bit in a hurry because our project development is stalled due to this bug ...

Also, to be honest, I'd be happy to contribute a PR :)

OK, I suppose I will reapply my cleanups on top of your fix.

Thanks @gsmet for the quick responses and looking at the PR!

Was this page helpful?
0 / 5 - 0 ratings