From 99f45f042eb91728394914fe10c175ef58810a8a Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 24 Apr 2023 13:30:57 +0200 Subject: [PATCH] HHH-16492 Hibernate 6 does not auto flush when calling Query.stream() with NativeQuery --- .../query/spi/AbstractSelectionQuery.java | 24 +++++++--- .../internal/NativeSelectQueryPlanImpl.java | 7 +-- .../query/sqm/internal/QuerySqmImpl.java | 44 ------------------- .../sqm/internal/SqmSelectionQueryImpl.java | 4 -- 4 files changed, 19 insertions(+), 60 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 b11e772720..9c647ab352 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 @@ -385,7 +385,9 @@ public abstract class AbstractSelectionQuery protected void beforeQuery() { getQueryParameterBindings().validate(); - getSession().prepareForQueryExecution(false); + getSession().prepareForQueryExecution( + requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) + ); prepareForExecution(); assert sessionFlushMode == null; @@ -407,6 +409,14 @@ public abstract class AbstractSelectionQuery protected abstract void prepareForExecution(); protected void afterQuery(boolean success) { + afterQuery(); + if ( !getSession().isTransactionInProgress() ) { + getSession().getJdbcCoordinator().getLogicalConnection().afterTransaction(); + } + getSession().afterOperation( success ); + } + + protected void afterQuery() { if ( sessionFlushMode != null ) { getSession().setHibernateFlushMode( sessionFlushMode ); sessionFlushMode = null; @@ -415,10 +425,6 @@ public abstract class AbstractSelectionQuery getSession().setCacheMode( sessionCacheMode ); sessionCacheMode = null; } - if ( !getSession().isTransactionInProgress() ) { - getSession().getJdbcCoordinator().getLogicalConnection().afterTransaction(); - } - getSession().afterOperation( success ); } protected boolean requiresTxn(LockMode lockMode) { @@ -434,7 +440,13 @@ public abstract class AbstractSelectionQuery @Override public ScrollableResultsImplementor scroll(ScrollMode scrollMode) { - return doScroll( scrollMode ); + beforeQuery(); + try { + return doScroll( scrollMode ); + } + finally { + afterQuery(); + } } protected abstract ScrollableResultsImplementor doScroll(ScrollMode scrollMode); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java index 1218212117..35eab5ee8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java @@ -13,9 +13,7 @@ import java.util.List; import java.util.Set; import org.hibernate.ScrollMode; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.EmptyScrollableResults; import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.spi.DomainQueryExecutionContext; @@ -96,10 +94,7 @@ public class NativeSelectQueryPlanImpl implements NativeSelectQueryPlan { affectedTableNames ); - final SharedSessionContractImplementor session = executionContext.getSession(); - final SessionFactoryImplementor factory = session.getFactory(); - final JdbcServices jdbcServices = factory.getJdbcServices(); - return jdbcServices.getJdbcSelectExecutor().list( + return executionContext.getSession().getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, SqmJdbcExecutionContextAdapter.usingLockingAndPaging( executionContext ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index 003c798548..6fc3b71894 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -16,9 +16,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.function.Supplier; -import java.util.stream.Stream; import org.hibernate.CacheMode; import org.hibernate.FlushMode; @@ -508,7 +506,6 @@ public class QuerySqmImpl protected List doList() { verifySelect(); - getSession().prepareForQueryExecution( requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) ); final SqmSelectStatement sqmStatement = (SqmSelectStatement) getSqmStatement(); final boolean containsCollectionFetches = sqmStatement.containsCollectionFetches() || AppliedGraphs.containsCollectionFetches( @@ -629,7 +626,6 @@ public class QuerySqmImpl @Override protected ScrollableResultsImplementor doScroll(ScrollMode scrollMode) { - getSession().prepareForQueryExecution( requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) ); return resolveSelectQueryPlan().performScroll( scrollMode, this ); } @@ -1076,46 +1072,6 @@ public class QuerySqmImpl } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // select execution - - @Override - public List list() { - return super.list(); - } - - @Override - public ScrollableResultsImplementor scroll() { - return super.scroll(); - } - - @Override - public ScrollableResultsImplementor scroll(ScrollMode scrollMode) { - return super.scroll( scrollMode ); - } - - @Override - public Stream stream() { - //noinspection unchecked - return super.stream(); - } - - @Override - public R uniqueResult() { - return super.uniqueResult(); - } - - @Override - public R getSingleResult() { - return super.getSingleResult(); - } - - @Override - public Optional uniqueResultOptional() { - return super.uniqueResultOptional(); - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Named query externalization diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java index 2e10607a1e..f91ae92253 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java @@ -256,8 +256,6 @@ public class SqmSelectionQueryImpl extends AbstractSelectionQuery implemen } protected List doList() { - getSession().prepareForQueryExecution( requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) ); - final SqmSelectStatement sqmStatement = (SqmSelectStatement) getSqmStatement(); final boolean containsCollectionFetches = sqmStatement.containsCollectionFetches(); final boolean hasLimit = hasLimit( sqmStatement, getQueryOptions() ); @@ -330,8 +328,6 @@ public class SqmSelectionQueryImpl extends AbstractSelectionQuery implemen @Override protected ScrollableResultsImplementor doScroll(ScrollMode scrollMode) { - getSession().prepareForQueryExecution( requiresTxn( getQueryOptions().getLockOptions().findGreatestLockMode() ) ); - return resolveQueryPlan().performScroll( scrollMode, this ); }