question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Reactive Hibernate w/ Panache insert two entities within the same persistence context

See original GitHub issue

Describe 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:closed
  • Created 2 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
Sannecommented, Feb 22, 2022

So how exactly can I close the session after the first persistence context finishes (with a success or failure)? Is there a helper function that I can call in Panache that closes that session after the fact? Sorry for the rudimentary question(s), I am still a bit new to reactive in general and would love to know how to do this.

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 the withTransaction() method completes it will happen after that session is closed - so technically you can chain multiple withTransaction blocks to define independent sequential operations: each with its own transaction and its own session.

1reaction
LazaroR94commented, Feb 22, 2022

So how exactly can I close the session after the first persistence context finishes (with a success or failure)? Is there a helper function that I can call in Panache that closes that session after the fact? Sorry for the rudimentary question(s), I am still a bit new to reactive in general and would love to know how to do this.

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 the withTransaction() method completes it will happen after that session is closed - so technically you can chain multiple withTransaction 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 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Simplified Hibernate ORM with Panache - Quarkus
Setting up and configuring Hibernate ORM with Panache. To get started: add your settings in application.properties. annotate your entities with @Entity.
Read more >
Why can I have two entites in the same persistence context ...
Through this post I try to see that problems can arise by allowing two entities have the same id in a persistence context....
Read more >
Hibernate Reactive - Getting Started Guide - Thorben Janssen
Using Hibernate Reactive, you can query your entities in the same way you do with Hibernate ORM. You can call the find method...
Read more >
Home of Quarkus Cheat-Sheet - GitHub Pages
Quarkus allow you to have multiple configuration in the same file ( application.properties ). ... Quarkus works with JPA(Hibernate) as persistence solution.
Read more >
JPA/Hibernate Persistence Context - Baeldung
Within the persistence context, the entity instances and their lifecycle are managed. The EntityManager API is used to create and remove ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found