quarkus: Reactive REST Client breaks Hibernate Reactive Transactions

Describe the bug

When combining the Reactive REST client with Hibernate Reactive, the Reactive REST client seems to break Context Propagation, leading to Hibernate Transactions not working as intended.

Expected behavior

Using Reactive REST Client does not have any negative effects on Hibernate Reactive

Actual behavior

Using Reactive REST Client will break Hibernate Reactive Transactions because a call to sessionFactory.withSession() within an existing transaction will result in a new session being created instead of re-using the previously existing session residing in context.

How to Reproduce?

Reproducer: https://github.com/markusdlugi/hibernate-reactive-with-transaction (don’t get confused by the naming)

Steps to reproduce the behavior:

  1. Run the application
  2. Open http://localhost:8080/test. It will fail with java.lang.IllegalStateException: Couldn't find author 1
  3. Remove the REST call (TestResource line 48). If you repeat the test, it will now work, you get an author and some books.
  4. Revert your change and add the REST call again. The test will fail again.
  5. Remove the Hibernate Transaction by replacing .withTransaction((session, tx) in line 43 with .withSession(session. The test will now work again, even though the REST call is still in place.

It seems like after the REST call, the session2 in the reproducer is not the same session as session1 where the entity was initially persisted. This leads to the error. Seems like the Reactive REST client messes up the context propagation.

Not sure why the example works when getting rid of the transaction entirely, though.

Output of uname -a or ver

Microsoft Windows [Version 10.0.18363.1556]

Output of java -version

OpenJDK 64-Bit Server VM Corretto-11.0.10.9.1 (build 11.0.10+9-LTS, mixed mode)

GraalVM version (if different from Java)

N/A

Quarkus version or git rev

2.0.3.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.6.3

Additional information

Possibly related to #16949? But this one seems more severe because you cannot mix Hibernate Reactive Transactions and the REST client at all.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 31 (27 by maintainers)

Commits related to this issue

Most upvoted comments

Actually, we get notified from the client on a VertxThread which has a non-null context, and then from that thread, we grab a random EventLoop thread instead of using the one we are on https://github.com/quarkusio/quarkus/blob/2.1.0.Final/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/RestClientRequestContext.java#L205 (remember there are one event loop thread per CPU) and execute the callback on that thread, which does not have a context. So it looks like our bug after all.

@geoand ok thanks for clarifying, that matches the same as what @DavideD and myself are seeing in debug.

Ok now I understand what Stuart said about affinity. Yes we will need that http client which is invoked to not have the context being lost. This doesn’t seem related to Hibernate Reactive and I’m not familiar with these integrations… who can own this?

It’s Hibernate Reactive that fails in this case because when the rest client comes back it’s on a different Vert.x thread.

oh, now I get it. Then it’s probably my own fault, I’ll need to review our internal assertions. Thanks, I’ll check!

I’ve passed on the question to the Vert.x team on discord. Pretty sure @cescoffier is on PTO: https://discord.com/channels/751380286071242794/751398938459766895/872058623394738236

I always took it for granted that Vert.x had thread affinity, but that doesn’t seem to be the case. I assume we would need input from the Vert.x folks on this one.

I’ll try and have a look soon

Just updated the reproducer and tested it with that version again. It does also exist in 2.1.0.Final.