From 8573f9448dd8dfcdcb7b3d357a94c4d27edbe664 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Thu, 4 Dec 2025 16:22:59 +0100 Subject: [PATCH] HHH-19977 Relax scopes to allow HR to run a reactive flush A native query might need to run a flush operation before it's executed. Hibernate Reactive have to run a reactive flush. By relaxing the scopes of these methods, we can avoid some code duplication. --- .../query/spi/AbstractSelectionQuery.java | 16 ++++++++++++++-- .../query/sql/internal/NativeQueryImpl.java | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java index b6d2f7cc540f..2238e267c70c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java @@ -180,16 +180,28 @@ protected void beforeQuery() { session.prepareForQueryExecution( requiresTxn( options.getLockOptions().getLockMode() ) ); prepareForExecution(); + prepareSessionFlushMode( session ); + prepareSessionCacheMode( session ); + } - assert sessionFlushMode == null; - assert sessionCacheMode == null; + /* + * Used by Hibernate Reactive + */ + protected void prepareSessionFlushMode(SharedSessionContractImplementor session) { + assert sessionFlushMode == null; final var effectiveFlushMode = getQueryOptions().getFlushMode(); if ( effectiveFlushMode != null && session instanceof SessionImplementor statefulSession ) { sessionFlushMode = statefulSession.getHibernateFlushMode(); statefulSession.setHibernateFlushMode( effectiveFlushMode ); } + } + /* + * Used by Hibernate Reactive + */ + protected void prepareSessionCacheMode(SharedSessionContractImplementor session) { + assert sessionCacheMode == null; final var effectiveCacheMode = getCacheMode(); if ( effectiveCacheMode != null ) { sessionCacheMode = session.getCacheMode(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index b960851b3c3a..806fb177c50a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -554,6 +554,14 @@ public boolean hasCallbackActions() { return callback != null && callback.hasAfterLoadActions(); } + /* + * Used by Hibernate Reactive + */ + @Override + protected void resetCallback() { + callback = null; + } + @Override public QueryParameterBindings getQueryParameterBindings() { return parameterBindings; @@ -722,14 +730,17 @@ protected void prepareForExecution() { getSession().flush(); } // Reset the callback before every execution - callback = null; + resetCallback(); } // Otherwise, the application specified query spaces via the Hibernate // SynchronizeableQuery and so the query will already perform a partial // flush according to the defined query spaces - no need for a full flush. } - private boolean shouldFlush() { + /* + * Used by Hibernate Reactive + */ + protected boolean shouldFlush() { if ( getSession().isTransactionInProgress() ) { final var flushMode = getQueryOptions().getFlushMode(); return switch ( flushMode == null ? getSession().getHibernateFlushMode() : flushMode ) {