Reactive Hibernate w/ Panache insert two entities within the same persistence context
See original GitHub issueDescribe the bug
Hello, I have created an application that performs processing on a method and inserts into three tables. If processing on those three tables fails then the message is published to a Kafka DLQ in which the message then gets sent to the database for manual processing at a later time. Being new to reactive hibernate, I am not sure how I can make two separate inserts within the same persistence context seeing as I insert in one thread but then attempt to insert the same managed entity on another thread.
This is the error that I get when my processing fails the business-as-usual stage and fails over to get sent to the database for manual processing:
org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.HibernateException: Illegal attempt to associate a ManagedEntity with two open persistence contexts. EntityEntry[MyEntity#786e52e3-c5c1-446f-b8b8-f4183cc60585](MANAGED)
This is how I have my repositories set up to save to the database:
Panache.withTransaction {
SomeRepo.persist(entity).chain { ->
SomeRepo.flush()
}
}
What am I doing wrong here?
Expected behavior
For the managed entity from the first thread to be able to get inserted into a different table within the same persistence context instead of opening up two persistence contexts.
Actual behavior
org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.HibernateException: Illegal attempt to associate a ManagedEntity with two open persistence contexts. EntityEntry[MyEntity#786e52e3-c5c1-446f-b8b8-f4183cc60585](MANAGED)
How to Reproduce?
No response
Output of uname -a
or ver
No response
Output of java -version
Java 11.0.12
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.7.1
Build tool (ie. output of mvnw --version
or gradlew --version
)
Gradle 7.3.3
Additional information
No response
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (6 by maintainers)
No problem 😃 So with Panache there is the “assumption” that everything that you do in the current web request is to be handled by the same Hibernate Session: it does lookup a Session in the current request scope, and if it doesn’t find one it triggers the CDI factory which creates a Session bount to the lifecycle of that scope.
Essentially it’s automatic - but it’s only useful for simple use cases.
In situations like yours when you need to have control of the Session boundaries, don’t use Panache so that the instance of session which you’re using is explicit.
To be clear: the method
SessionFactory.withTransaction( actions )
will create both a Session and a Transaction object, scoped for that action. Whatever you do after thewithTransaction()
method completes it will happen after that session is closed - so technically you can chain multiplewithTransaction
blocks to define independent sequential operations: each with its own transaction and its own session.Thank you so much, I have removed Panache and just used the
hibernate-reactive-orm
implementation and that seems to be working like a charm. It sucks to know that Panache does this with it’s simplicity mindset but it’s also a nice to know 😃