Skip to content

Allow using both of Hibernate Reactive's CDI-injected Session and StatelessSession in the same transaction when using @Transactional#53509

Merged
gsmet merged 4 commits intoquarkusio:mainfrom
yrodiere:i52828
Apr 13, 2026
Merged

Allow using both of Hibernate Reactive's CDI-injected Session and StatelessSession in the same transaction when using @Transactional#53509
gsmet merged 4 commits intoquarkusio:mainfrom
yrodiere:i52828

Conversation

@yrodiere
Copy link
Copy Markdown
Member

@yrodiere yrodiere commented Apr 8, 2026

@quarkus-bot
Copy link
Copy Markdown

quarkus-bot bot commented Apr 8, 2026

/cc @gsmet (hibernate-orm)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

🙈 The PR is closed and the preview is expired.

@quarkus-bot quarkus-bot bot added the area/narayana Transactions / Narayana label Apr 9, 2026
@yrodiere yrodiere marked this pull request as ready for review April 9, 2026 15:59
@yrodiere yrodiere requested a review from lucamolteni April 9, 2026 16:01
@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@lucamolteni lucamolteni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to hear it (somehow) worked already :)

Copy link
Copy Markdown
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a small suggestion but feel free to merge if you don't think it has value.

…sSession

This test confirms that blocking Hibernate ORM already allows using both
regular Session and StatelessSession within the same transaction. Both
session types can be used together, and changes from both are properly
committed or rolled back together.

This serves as a reference implementation before enabling the same
capability in Hibernate Reactive.

Assisted-By: Claude Code <noreply@anthropic.com>
… package

Because that's the convention for classes that are not API.
Technically this should be SPI, but since for now we only intend to
use these classes in the core Quarkus project, this will do.
…eactive-transactions

Moved TransactionalContextPool and TransactionalContextConnection from
hibernate-reactive to reactive-transactions module, as they are not specific
to Hibernate Reactive and are used by the transaction interceptors.

Additionally, introduced getCurrentConnectionFromVertxContext() method in
TransactionalContextPool for consistent access to the current connection
from the Vert.x context.

Assisted-By: Claude Code <noreply@anthropic.com>
…action

This change removes the artificial restriction that prevented using both
Mutiny.Session and Mutiny.StatelessSession within the same @transactional
method in Hibernate Reactive, bringing it in line with blocking Hibernate ORM.

Key changes:
- Added thread-safe connection reuse in TransactionalContextPool: when a
  second session type requests a connection within the same transaction, it
  reuses the existing connection from the Vert.x context. Uses VarHandle
  with compareAndSet to prevent race conditions when both session types
  request connections concurrently.
- Extracted ConnectionHolder as a package-protected class that ensures only
  one connection is created per transaction even with concurrent access,
  using a Promise pattern inspired by Hibernate Reactive's ProxyConnection
- Made TransactionalContextConnection.close() a no-op to prevent premature
  connection closure, letting only TransactionalInterceptorBase close the
  actual connection at transaction end
- Changed TransactionalContextPool.getCurrentConnectionFromVertxContext() to
  return a Future instead of the connection directly, allowing callers to
  handle async connection availability
- Updated TransactionalInterceptorBase.connectionFromContext() to return
  Uni<SqlConnection> and all its callers to handle null checks before
  converting to Uni
- Updated TransactionalInterceptorBase to use
  TransactionalContextPool.closeAndClearCurrentConnection() to properly
  close the connection and clear it from the Vert.x context
- Removed validation checks in HibernateReactiveRecorder that threw
  IllegalStateException when mixing session types
- Transformed MixStatelessStatefulSessionTest from negative (expecting
  failures) to positive tests verifying both session types work together,
  share connections, and commit/rollback together
- Updated documentation to explain that mixing is now supported and both
  session types share the same underlying connection

Both session types can now coexist in the same transaction, using the
appropriate session type for different operations (e.g., StatelessSession
for bulk operations, regular Session for operations requiring caching).

Fixes quarkusio#52828

Assisted-By: Claude Code <noreply@anthropic.com>
@yrodiere yrodiere marked this pull request as ready for review April 13, 2026 09:21
@yrodiere yrodiere added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Apr 13, 2026
@quarkus-bot

This comment has been minimized.

@quarkus-bot
Copy link
Copy Markdown

quarkus-bot bot commented Apr 13, 2026

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit 1e00206.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

@quarkus-bot
Copy link
Copy Markdown

quarkus-bot bot commented Apr 13, 2026

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 1e00206.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.


Flaky tests - Develocity

⚙️ Gradle Tests - JDK 25

📦 integration-tests/gradle

io.quarkus.gradle.CustomConfigSourcesTest.testCustomConfigSources - History

  • Gradle build failed with exit code 1 - java.lang.AssertionError
Details
java.lang.AssertionError: Gradle build failed with exit code 1
	at io.quarkus.gradle.QuarkusGradleWrapperTestBase.runGradleWrapper(QuarkusGradleWrapperTestBase.java:173)
	at io.quarkus.gradle.QuarkusGradleWrapperTestBase.runGradleWrapper(QuarkusGradleWrapperTestBase.java:87)
	at io.quarkus.gradle.QuarkusGradleWrapperTestBase.runGradleWrapper(QuarkusGradleWrapperTestBase.java:82)
	at io.quarkus.gradle.CustomConfigSourcesTest.testCustomConfigSources(CustomConfigSourcesTest.java:14)

@yrodiere yrodiere requested a review from gsmet April 13, 2026 11:11
@gsmet gsmet merged commit 15e7db4 into quarkusio:main Apr 13, 2026
76 of 77 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.35 - main milestone Apr 13, 2026
@quarkus-bot quarkus-bot bot added kind/enhancement New feature or request and removed triage/waiting-for-ci Ready to merge when CI successfully finishes labels Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hibernate Reactive: allow mixing Session and StatelessSession in the same transaction

3 participants