HHH-15942 introduce QueryFlushMode for specifying whether a query flushes or not

- replaces FlushModeType in the annotation package
- much less confusing when applied to a Query
  * what do MANUAL and COMMIT mean for a Query?
  * how is AUTO useful for a Query?

- also make Query.getHibernateFlushMode() obey its
  documented semantics by returning the session
  flush mode instead of null when unset
This commit is contained in:
Gavin 2022-12-28 14:54:37 +01:00 committed by Gavin King
parent 5f8bf125fc
commit 52e185b194
30 changed files with 641 additions and 94 deletions

View File

@ -18,9 +18,16 @@ import jakarta.persistence.FlushModeType;
* <p>
* For example, {@link #COMMIT} specifies that the session flushes
* automatically when the transaction is about to commit.
* <p>
* This enumeration represents options which may be
* {@linkplain Session#setHibernateFlushMode set at the session
* level}, and competes with the JPA-defined enumeration
* {@link jakarta.persistence.FlushModeType}. Alternatively, a
* {@link org.hibernate.query.QueryFlushMode QueryFlushMode} may
* be specified for a given query.
*
* @see Session#setHibernateFlushMode
* @see org.hibernate.query.CommonQueryContract#setHibernateFlushMode
* @see org.hibernate.query.QueryFlushMode
*
* @author Gavin King
*/

View File

@ -199,7 +199,7 @@ public interface Session extends SharedSessionContract, EntityManager {
void flush();
/**
* Set the current {@link FlushModeType JPA flush mode} for this session.
* Set the current {@linkplain FlushModeType JPA flush mode} for this session.
* <p>
* <em>Flushing</em> is the process of synchronizing the underlying persistent
* store with persistable state held in memory. The current flush mode determines

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.annotations;
import org.hibernate.query.QueryFlushMode;
/**
* Enumeration extending the {@linkplain jakarta.persistence.FlushModeType JPA flush modes}
* with flush modes specific to Hibernate, and a "null" mode, {@link #PERSISTENCE_CONTEXT},
@ -14,9 +16,12 @@ package org.hibernate.annotations;
*
* @author Carlos Gonzalez-Cadenas
*
* @see NamedQuery
* @see NamedNativeQuery
* @see NamedQuery#flushMode
* @see NamedNativeQuery#flushMode
*
* @deprecated use {@link QueryFlushMode}
*/
@Deprecated(since="7")
public enum FlushModeType {
/**
* Corresponds to {@link org.hibernate.FlushMode#ALWAYS}.

View File

@ -13,6 +13,7 @@ import java.lang.annotation.Target;
import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
import org.hibernate.CacheMode;
import org.hibernate.query.QueryFlushMode;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
@ -63,12 +64,25 @@ public @interface NamedNativeQuery {
*/
String resultSetMapping() default "";
/**
* Determines whether the session should be flushed before
* executing the query.
*
* @see org.hibernate.query.CommonQueryContract#setQueryFlushMode(QueryFlushMode)
*
* @since 7.0
*/
QueryFlushMode flush() default QueryFlushMode.DEFAULT;
/**
* The flush mode for the query.
*
* @see org.hibernate.query.CommonQueryContract#setFlushMode(jakarta.persistence.FlushModeType)
* @see org.hibernate.jpa.HibernateHints#HINT_FLUSH_MODE
*
* @deprecated use {@link #flush()}
*/
@Deprecated(since = "7")
FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT;
/**

View File

@ -15,6 +15,7 @@ import jakarta.persistence.CacheStoreMode;
import jakarta.persistence.EntityManager;
import org.hibernate.CacheMode;
import org.hibernate.query.QueryFlushMode;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
@ -58,12 +59,25 @@ public @interface NamedQuery {
*/
Class<?> resultClass() default void.class;
/**
* Determines whether the session should be flushed before
* executing the query.
*
* @see org.hibernate.query.CommonQueryContract#setQueryFlushMode(QueryFlushMode)
*
* @since 7.0
*/
QueryFlushMode flush() default QueryFlushMode.DEFAULT;
/**
* The flush mode for this query.
*
* @see org.hibernate.query.CommonQueryContract#setFlushMode(jakarta.persistence.FlushModeType)
* @see org.hibernate.jpa.HibernateHints#HINT_FLUSH_MODE
*
* @deprecated use {@link #flush()}
*/
@Deprecated(since = "7")
FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT;
/**

View File

@ -16,6 +16,7 @@ import java.util.function.Supplier;
import org.hibernate.AnnotationException;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.LockOptions;
import org.hibernate.annotations.FlushModeType;
import org.hibernate.annotations.HQLSelect;
@ -35,6 +36,7 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.jpa.HibernateHints;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.models.internal.util.StringHelper;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
@ -271,7 +273,7 @@ public abstract class QueryBinder {
.setCacheMode(getCacheMode(namedNativeQuery.cacheRetrieveMode(), namedNativeQuery.cacheStoreMode()))
.setTimeout(timeout < 0 ? null : timeout)
.setFetchSize(fetchSize < 0 ? null : fetchSize)
.setFlushMode(getFlushMode(namedNativeQuery.flushMode()))
.setFlushMode(getFlushMode(namedNativeQuery.flush(), namedNativeQuery.flushMode()))
.setReadOnly(namedNativeQuery.readOnly())
.setQuerySpaces(querySpaces)
.setComment(nullIfEmpty(namedNativeQuery.comment()));
@ -412,7 +414,7 @@ public abstract class QueryBinder {
.setCacheMode(getCacheMode(namedQuery.cacheRetrieveMode(), namedQuery.cacheStoreMode()))
.setTimeout(timeout < 0 ? null : timeout)
.setFetchSize(fetchSize < 0 ? null : fetchSize)
.setFlushMode(getFlushMode(namedQuery.flushMode()))
.setFlushMode(getFlushMode(namedQuery.flush(), namedQuery.flushMode()))
.setReadOnly(namedQuery.readOnly())
.setComment(nullIfEmpty(namedQuery.comment()));
}
@ -422,6 +424,12 @@ public abstract class QueryBinder {
return cacheMode == null ? CacheMode.NORMAL : cacheMode;
}
private static FlushMode getFlushMode(QueryFlushMode queryFlushMode, FlushModeType flushModeType) {
return queryFlushMode == QueryFlushMode.DEFAULT
? getFlushMode( flushModeType )
: FlushModeTypeHelper.getFlushMode(queryFlushMode);
}
private static FlushMode getFlushMode(FlushModeType flushModeType) {
return switch ( flushModeType ) {
case ALWAYS -> FlushMode.ALWAYS;

View File

@ -24,6 +24,7 @@ import org.hibernate.models.spi.SourceModelBuildingContext;
import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
import org.hibernate.query.QueryFlushMode;
@SuppressWarnings({ "ClassExplicitlyAnnotation", "unused" })
@jakarta.annotation.Generated("org.hibernate.orm.build.annotations.ClassGeneratorProcessor")
@ -33,6 +34,7 @@ public class NamedNativeQueryAnnotation implements NamedNativeQuery {
private Class<?> resultClass;
private String resultSetMapping;
private FlushModeType flushMode;
private QueryFlushMode flush;
boolean cacheable;
String cacheRegion;
int fetchSize;
@ -51,6 +53,7 @@ public class NamedNativeQueryAnnotation implements NamedNativeQuery {
resultClass = void.class;
resultSetMapping = "";
flushMode = FlushModeType.PERSISTENCE_CONTEXT;
flush = QueryFlushMode.DEFAULT;
cacheable = false;
cacheRegion = "";
fetchSize = -1;
@ -72,6 +75,7 @@ public class NamedNativeQueryAnnotation implements NamedNativeQuery {
this.resultClass = annotation.resultClass();
this.resultSetMapping = annotation.resultSetMapping();
this.flushMode = annotation.flushMode();
this.flush = annotation.flush();
this.cacheable = annotation.cacheable();
this.cacheRegion = annotation.cacheRegion();
this.fetchSize = annotation.fetchSize();
@ -97,6 +101,7 @@ public class NamedNativeQueryAnnotation implements NamedNativeQuery {
this.resultClass = (Class<?>) attributeValues.get( "resultClass" );
this.resultSetMapping = (String) attributeValues.get( "resultSetMapping" );
this.flushMode = (FlushModeType) attributeValues.get( "flushMode" );
this.flush = (QueryFlushMode) attributeValues.get( "flush" );
this.cacheable = (boolean) attributeValues.get( "cacheable" );
this.cacheRegion = (String) attributeValues.get( "cacheRegion" );
this.fetchSize = (int) attributeValues.get( "fetchSize" );
@ -152,6 +157,15 @@ public class NamedNativeQueryAnnotation implements NamedNativeQuery {
this.resultSetMapping = value;
}
@Override
public QueryFlushMode flush() {
return flush;
}
public void flush(QueryFlushMode value) {
this.flush = value;
}
@Override
public FlushModeType flushMode() {
return flushMode;

View File

@ -19,6 +19,7 @@ import org.hibernate.models.spi.SourceModelBuildingContext;
import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
import org.hibernate.query.QueryFlushMode;
import static org.hibernate.boot.models.xml.internal.QueryProcessing.interpretFlushMode;
@ -29,6 +30,7 @@ public class NamedQueryAnnotation implements NamedQuery {
private String query;
private Class<?> resultClass;
private FlushModeType flushMode;
private QueryFlushMode flush;
boolean cacheable;
String cacheRegion;
int fetchSize;
@ -44,6 +46,7 @@ public class NamedQueryAnnotation implements NamedQuery {
public NamedQueryAnnotation(SourceModelBuildingContext modelContext) {
resultClass = void.class;
flushMode = FlushModeType.PERSISTENCE_CONTEXT;
flush = QueryFlushMode.DEFAULT;
cacheable = false;
cacheRegion = "";
fetchSize = -1;
@ -62,6 +65,7 @@ public class NamedQueryAnnotation implements NamedQuery {
this.query = annotation.query();
this.resultClass = annotation.resultClass();
this.flushMode = annotation.flushMode();
this.flush = annotation.flush();
this.cacheable = annotation.cacheable();
this.cacheRegion = annotation.cacheRegion();
this.fetchSize = annotation.fetchSize();
@ -84,6 +88,7 @@ public class NamedQueryAnnotation implements NamedQuery {
this.query = (String) attributeValues.get( "query" );
this.resultClass = (Class<?>) attributeValues.get( "resultClass" );
this.flushMode = (FlushModeType) attributeValues.get( "flushMode" );
this.flush = (QueryFlushMode) attributeValues.get( "flush" );
this.cacheable = (boolean) attributeValues.get( "cacheable" );
this.cacheRegion = (String) attributeValues.get( "cacheRegion" );
this.fetchSize = (int) attributeValues.get( "fetchSize" );
@ -128,6 +133,15 @@ public class NamedQueryAnnotation implements NamedQuery {
this.resultClass = value;
}
@Override
public QueryFlushMode flush() {
return flush;
}
public void flush(QueryFlushMode value) {
this.flush = value;
}
@Override
public FlushModeType flushMode() {
return flushMode;

View File

@ -10,8 +10,8 @@ package org.hibernate.jpa.internal.util;
import java.util.Locale;
import jakarta.persistence.FlushModeType;
import org.hibernate.AssertionFailure;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.MappingException;
import org.jboss.logging.Logger;
@ -28,35 +28,55 @@ public class FlushModeTypeHelper {
}
public static FlushModeType getFlushModeType(FlushMode flushMode) {
if ( flushMode == FlushMode.ALWAYS ) {
log.debug( "Interpreting Hibernate FlushMode#ALWAYS to JPA FlushModeType#AUTO; may cause problems if relying on FlushMode#ALWAYS-specific behavior" );
return FlushModeType.AUTO;
if ( flushMode == null ) {
return null;
}
else if ( flushMode == FlushMode.MANUAL ) {
log.debug( "Interpreting Hibernate FlushMode#MANUAL to JPA FlushModeType#COMMIT; may cause problems if relying on FlushMode#MANUAL-specific behavior" );
return FlushModeType.COMMIT;
}
else if ( flushMode == FlushMode.COMMIT ) {
return FlushModeType.COMMIT;
}
else if ( flushMode == FlushMode.AUTO ) {
return FlushModeType.AUTO;
}
else {
throw new AssertionFailure( "unhandled FlushMode " + flushMode );
return switch (flushMode) {
case ALWAYS -> {
log.debug("Interpreting Hibernate FlushMode.ALWAYS as JPA FlushModeType.AUTO (may cause problems if relying on FlushMode.ALWAYS-specific behavior)");
yield FlushModeType.AUTO;
}
case MANUAL -> {
log.debug("Interpreting Hibernate FlushMode.MANUAL as JPA FlushModeType.COMMIT (may cause problems if relying on FlushMode.MANUAL-specific behavior)");
yield FlushModeType.COMMIT;
}
case COMMIT -> FlushModeType.COMMIT;
case AUTO -> FlushModeType.AUTO;
};
}
public static QueryFlushMode getForcedFlushMode(FlushMode flushMode) {
if ( flushMode == null ) {
return QueryFlushMode.DEFAULT;
}
return switch (flushMode) {
case ALWAYS -> QueryFlushMode.FLUSH;
case COMMIT, MANUAL -> QueryFlushMode.NO_FLUSH;
case AUTO ->
// this is not precisely correctly correct, but good enough
QueryFlushMode.DEFAULT;
};
}
public static FlushMode getFlushMode(FlushModeType flushModeType) {
if ( flushModeType == FlushModeType.AUTO ) {
return FlushMode.AUTO;
if ( flushModeType == null ) {
return null;
}
else if ( flushModeType == FlushModeType.COMMIT ) {
return FlushMode.COMMIT;
}
else {
throw new AssertionFailure( "unhandled FlushModeType " + flushModeType );
return switch (flushModeType) {
case AUTO -> FlushMode.AUTO;
case COMMIT -> FlushMode.COMMIT;
};
}
public static FlushMode getFlushMode(QueryFlushMode queryFlushMode) {
if ( queryFlushMode == null ) {
return null;
}
return switch (queryFlushMode) {
case FLUSH -> FlushMode.ALWAYS;
case NO_FLUSH -> FlushMode.MANUAL;
default -> null;
};
}
public static FlushMode interpretFlushMode(Object value) {

View File

@ -281,7 +281,7 @@ public interface ProcedureCall
@Override
ProcedureCall setParameter(int position, Date value, TemporalType temporalType);
@Override
@Override @Deprecated(since = "7")
ProcedureCall setFlushMode(FlushModeType flushMode);
@Override

View File

@ -809,7 +809,7 @@ public class ProcedureCallImpl<R>
isCacheable(),
getCacheRegion(),
getCacheMode(),
getHibernateFlushMode(),
getQueryOptions().getFlushMode(),
isReadOnly(),
getTimeout(),
getFetchSize(),

View File

@ -51,48 +51,86 @@ import jakarta.persistence.TemporalType;
*/
public interface CommonQueryContract {
/**
* The {@link QueryFlushMode} in effect for this query.
* <p>
* By default, this is {@link QueryFlushMode#DEFAULT}, and the
* {@link FlushMode} of the owning {@link Session} determines whether
* it is flushed.
*
* @see Session#getHibernateFlushMode()
*
* @since 7.0
*/
QueryFlushMode getQueryFlushMode();
/**
* Set the {@link QueryFlushMode} to use for this query.
*
* @see Session#getHibernateFlushMode()
*
* @since 7.0
*/
CommonQueryContract setQueryFlushMode(QueryFlushMode queryFlushMode);
/**
* The JPA {@link FlushModeType} in effect for this query. By default, the
* query inherits the {@link FlushMode} of the {@link Session} from which
* it originates.
*
* @see #getHibernateFlushMode
* @see Session#getHibernateFlushMode
* @see #getQueryFlushMode()
* @see #getHibernateFlushMode()
* @see Session#getHibernateFlushMode()
*
* @deprecated use {@link #getQueryFlushMode()}
*/
@Deprecated(since = "7")
FlushModeType getFlushMode();
/**
* Set the {@link FlushMode} in to use for this query.
*
* @implNote Setting to {@code null} ultimately indicates to use the
* FlushMode of the Session. Use {@link #setHibernateFlushMode} passing
* {@link FlushMode#MANUAL} instead to indicate that no automatic flushing
* should occur
* Set the {@link FlushMode} to use for this query.
* <p>
* Setting this to {@code null} ultimately indicates to use the
* {@link FlushMode} of the session. Use {@link #setHibernateFlushMode}
* passing {@link FlushMode#MANUAL} instead to indicate that no automatic
* flushing should occur.
*
* @see #getQueryFlushMode()
* @see #getHibernateFlushMode()
* @see Session#getHibernateFlushMode()
*
* @deprecated use {@link #setQueryFlushMode(QueryFlushMode)}
*/
@Deprecated(since = "7")
CommonQueryContract setFlushMode(FlushModeType flushMode);
/**
* The {@link FlushMode} in effect for this query. By default, the query
* The {@link FlushMode} in effect for this query. By default, the query
* inherits the {@code FlushMode} of the {@link Session} from which it
* originates.
*
* @see Session#getHibernateFlushMode
* @see #getQueryFlushMode()
* @see Session#getHibernateFlushMode()
*
* @deprecated use {@link #getQueryFlushMode()}
*/
@Deprecated(since = "7")
FlushMode getHibernateFlushMode();
/**
* Set the current {@link FlushMode} in effect for this query.
*
* @implNote Setting to {@code null} ultimately indicates to use the
* {@link FlushMode} of the Session. Use {@link FlushMode#MANUAL}
* {@link FlushMode} of the session. Use {@link FlushMode#MANUAL}
* instead to indicate that no automatic flushing should occur.
*
* @see #getQueryFlushMode()
* @see #getHibernateFlushMode()
* @see Session#getHibernateFlushMode()
*
* @deprecated use {@link #setQueryFlushMode(QueryFlushMode)}
*/
@Deprecated(since = "7")
CommonQueryContract setHibernateFlushMode(FlushMode flushMode);
/**

View File

@ -14,7 +14,6 @@ import java.util.Map;
import org.hibernate.FlushMode;
import org.hibernate.Incubating;
import org.hibernate.Session;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.Parameter;
@ -81,10 +80,10 @@ public interface MutationQuery extends CommonQueryContract {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant returns
@Override
@Override @Deprecated(since = "7")
MutationQuery setFlushMode(FlushModeType flushMode);
@Override
@Override @Deprecated(since = "7")
MutationQuery setHibernateFlushMode(FlushMode flushMode);
@Override
@ -209,4 +208,7 @@ public interface MutationQuery extends CommonQueryContract {
@Override
MutationQuery setProperties(@SuppressWarnings("rawtypes") Map bean);
@Override
MutationQuery setQueryFlushMode(QueryFlushMode queryFlushMode);
}

View File

@ -554,10 +554,13 @@ public interface NativeQuery<T> extends Query<T>, SynchronizeableQuery {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// covariant overrides - Query
@Override
@Override @Deprecated(since = "7")
NativeQuery<T> setHibernateFlushMode(FlushMode flushMode);
@Override
NativeQuery<T> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override @Deprecated(since = "7")
NativeQuery<T> setFlushMode(FlushModeType flushMode);
@Override

View File

@ -851,9 +851,12 @@ public interface Query<R> extends SelectionQuery<R>, MutationQuery, TypedQuery<R
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// covariant overrides - CommonQueryContract
@Override
@Override @Deprecated(since = "7")
Query<R> setHibernateFlushMode(FlushMode flushMode);
@Override
Query<R> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override
Query<R> setCacheable(boolean cacheable);
@ -914,7 +917,7 @@ public interface Query<R> extends SelectionQuery<R>, MutationQuery, TypedQuery<R
@Override
Query<R> disableFetchProfile(String profileName);
@Override
@Override @Deprecated(since = "7")
Query<R> setFlushMode(FlushModeType flushMode);
@Override

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.query;
/**
* Enumerates the possible flush modes for execution of a
* {@link org.hibernate.query.Query}. An explicitly-specified
* {@linkplain Query#setQueryFlushMode(QueryFlushMode)
* query-level flush mode} overrides the current
* {@linkplain org.hibernate.Session#getHibernateFlushMode()
* flush mode of the session}.
*
* @since 7.0
*
* @see CommonQueryContract#setQueryFlushMode(QueryFlushMode)
* @see org.hibernate.annotations.NamedQuery#flush
* @see org.hibernate.annotations.NamedNativeQuery#flush
*
* @author Gavin King
*/
public enum QueryFlushMode {
/**
* Flush before executing the query.
*/
FLUSH,
/**
* Do not flush before executing the query.
*/
NO_FLUSH,
/**
* Let the owning {@link org.hibernate.Session session}
* decide whether to flush, depending on its current
* {@link org.hibernate.FlushMode}.
*
* @see org.hibernate.Session#getFlushMode()
*/
DEFAULT
}

View File

@ -295,12 +295,15 @@ public interface SelectionQuery<R> extends CommonQueryContract {
*/
SelectionQuery<R> disableFetchProfile(String profileName);
@Override
@Override @Deprecated(since = "7")
SelectionQuery<R> setFlushMode(FlushModeType flushMode);
@Override
@Override @Deprecated(since = "7")
SelectionQuery<R> setHibernateFlushMode(FlushMode flushMode);
@Override
SelectionQuery<R> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override
SelectionQuery<R> setTimeout(int timeout);
@ -421,14 +424,13 @@ public interface SelectionQuery<R> extends CommonQueryContract {
* the query inherits the {@link CacheMode} of the session from which
* it originates.
* <p>
* The {@link CacheMode} here describes reading-from/writing-to the
* entity/collection caches as we process query results. For caching
* of the actual query results, see {@link #isCacheable()} and
* {@link #getCacheRegion()}
* The {@link CacheMode} here affects the use of entity and collection
* caches as the query result set is processed. For caching of the actual
* query results, use {@link #isCacheable()} and {@link #getCacheRegion()}.
* <p>
* In order for this setting to have any affect, second-level caching
* would have to be enabled and the entities/collections in question
* configured for caching.
* must be enabled and the entities and collections must be eligible
* for storage in the second-level cache.
*
* @see Session#getCacheMode()
*/
@ -450,9 +452,9 @@ public interface SelectionQuery<R> extends CommonQueryContract {
/**
* Set the current {@link CacheMode} in effect for this query.
*
* @implNote Setting it to {@code null} ultimately indicates to use the
* {@code CacheMode} of the session.
* <p>
* Set it to {@code null} to indicate that the {@code CacheMode}
* of the {@link Session#getCacheMode() session} should be used.
*
* @see #getCacheMode()
* @see Session#setCacheMode(CacheMode)

View File

@ -14,6 +14,7 @@ import java.util.Map;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.graph.GraphSemantic;
@ -104,9 +105,12 @@ public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, N
return setTupleTransformer( transformer ).setResultListTransformer( transformer );
}
@Override
@Override @Deprecated(since = "7")
SqmQueryImplementor<R> setHibernateFlushMode(FlushMode flushMode);
@Override
SqmQueryImplementor<R> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override
SqmQueryImplementor<R> setMaxResults(int maxResult);
@ -116,7 +120,7 @@ public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, N
@Override
SqmQueryImplementor<R> setHint(String hintName, Object value);
@Override
@Override @Deprecated(since = "7")
SqmQueryImplementor<R> setFlushMode(FlushModeType flushMode);
@Override

View File

@ -17,6 +17,7 @@ import java.util.Set;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -178,7 +179,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
}
putIfNotNull( hints, HINT_COMMENT, getComment() );
putIfNotNull( hints, HINT_FLUSH_MODE, getHibernateFlushMode() );
putIfNotNull( hints, HINT_FLUSH_MODE, getQueryOptions().getFlushMode() );
putIfNotNull( hints, HINT_READONLY, getQueryOptions().isReadOnly() );
putIfNotNull( hints, HINT_FETCH_SIZE, getQueryOptions().getFetchSize() );
@ -521,7 +522,8 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
@Override
public FlushMode getHibernateFlushMode() {
return getQueryOptions().getFlushMode();
final FlushMode flushMode = getQueryOptions().getFlushMode();
return flushMode == null ? getSession().getHibernateFlushMode() : flushMode;
}
@Override
@ -530,6 +532,17 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
return this;
}
@Override
public QueryFlushMode getQueryFlushMode() {
return FlushModeTypeHelper.getForcedFlushMode( getQueryOptions().getFlushMode() );
}
@Override
public CommonQueryContract setQueryFlushMode(QueryFlushMode queryFlushMode) {
getQueryOptions().setFlushMode( FlushModeTypeHelper.getFlushMode(queryFlushMode) );
return this;
}
protected boolean applyJpaCacheRetrieveModeHint(CacheRetrieveMode retrieveMode) {
getQueryOptions().setCacheRetrieveMode( retrieveMode );
return true;

View File

@ -27,6 +27,7 @@ import jakarta.persistence.TemporalType;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -194,18 +195,21 @@ public abstract class AbstractQuery<R>
return this;
}
@Override
public QueryImplementor<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
super.setQueryFlushMode(queryFlushMode);
return this;
}
@Override
public FlushModeType getFlushMode() {
getSession().checkOpen();
final FlushMode flushMode = getQueryOptions().getFlushMode() == null
? getSession().getHibernateFlushMode()
: getQueryOptions().getFlushMode();
return FlushModeTypeHelper.getFlushModeType( flushMode );
// getSession().checkOpen();
return FlushModeTypeHelper.getFlushModeType( getHibernateFlushMode() );
}
@Override
public QueryImplementor<R> setFlushMode(FlushModeType flushModeType) {
getSession().checkOpen();
// getSession().checkOpen();
setHibernateFlushMode( FlushModeTypeHelper.getFlushMode( flushModeType ) );
return this;
}
@ -366,7 +370,7 @@ public abstract class AbstractQuery<R>
putIfNotNull( hints, HINT_COMMENT, getComment() );
putIfNotNull( hints, HINT_FETCH_SIZE, getQueryOptions().getFetchSize() );
putIfNotNull( hints, HINT_FLUSH_MODE, getHibernateFlushMode() );
putIfNotNull( hints, HINT_FLUSH_MODE, getQueryOptions().getFlushMode() );
if ( getCacheMode() != null ) {
putIfNotNull( hints, HINT_CACHE_MODE, getCacheMode() );

View File

@ -20,6 +20,7 @@ import java.util.stream.StreamSupport;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -31,6 +32,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.AppliedGraph;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
import org.hibernate.query.BindableType;
import org.hibernate.query.IllegalQueryOperationException;
@ -52,7 +54,6 @@ import jakarta.persistence.TemporalType;
import static java.util.Spliterators.spliteratorUnknownSize;
import static org.hibernate.CacheMode.fromJpaModes;
import static org.hibernate.FlushMode.fromJpaFlushMode;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_STORE_MODE;
import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_RETRIEVE_MODE;
@ -167,7 +168,7 @@ public abstract class AbstractSelectionQuery<R>
assert sessionFlushMode == null;
assert sessionCacheMode == null;
final FlushMode effectiveFlushMode = getHibernateFlushMode();
final FlushMode effectiveFlushMode = getQueryOptions().getFlushMode();
if ( effectiveFlushMode != null ) {
sessionFlushMode = session.getHibernateFlushMode();
session.setHibernateFlushMode( effectiveFlushMode );
@ -333,12 +334,12 @@ public abstract class AbstractSelectionQuery<R>
@Override
public FlushModeType getFlushMode() {
return getQueryOptions().getFlushMode().toJpaFlushMode();
return FlushModeTypeHelper.getFlushModeType( getHibernateFlushMode() );
}
@Override
public SelectionQuery<R> setFlushMode(FlushModeType flushMode) {
getQueryOptions().setFlushMode( fromJpaFlushMode( flushMode ) );
getQueryOptions().setFlushMode( FlushModeTypeHelper.getFlushMode( flushMode ) );
return this;
}
@ -566,6 +567,12 @@ public abstract class AbstractSelectionQuery<R>
return this;
}
@Override
public SelectionQuery<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
super.setQueryFlushMode(queryFlushMode);
return this;
}
@Override
public SelectionQuery<R> setTimeout(int timeout) {
super.setTimeout( timeout );

View File

@ -13,6 +13,7 @@ import java.util.Date;
import java.util.Map;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.query.BindableType;
import org.hibernate.query.CommonQueryContract;
import org.hibernate.query.ParameterMetadata;
@ -151,6 +152,9 @@ public interface SqmQuery extends CommonQueryContract {
@Override
SqmQuery setProperties(@SuppressWarnings("rawtypes") Map bean);
@Override
@Override @Deprecated(since = "7")
SqmQuery setHibernateFlushMode(FlushMode flushMode);
@Override
SqmQuery setQueryFlushMode(QueryFlushMode queryFlushMode);
}

View File

@ -22,6 +22,7 @@ import java.util.function.Supplier;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -55,7 +56,6 @@ import org.hibernate.query.TupleTransformer;
import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext;
import org.hibernate.query.internal.ParameterMetadataImpl;
import org.hibernate.query.internal.QueryOptionsImpl;
import org.hibernate.query.internal.QueryParameterBindingsImpl;
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.results.Builders;
@ -469,7 +469,7 @@ public class NativeQueryImpl<R>
isCacheable(),
getCacheRegion(),
getCacheMode(),
getHibernateFlushMode(),
getQueryOptions().getFlushMode(),
isReadOnly(),
getTimeout(),
getFetchSize(),
@ -607,7 +607,7 @@ public class NativeQueryImpl<R>
private boolean shouldFlush() {
if ( getSession().isTransactionInProgress() ) {
FlushMode effectiveFlushMode = getHibernateFlushMode();
FlushMode effectiveFlushMode = getQueryOptions().getFlushMode();
if ( effectiveFlushMode == null ) {
effectiveFlushMode = getSession().getHibernateFlushMode();
}
@ -1180,6 +1180,12 @@ public class NativeQueryImpl<R>
return this;
}
@Override
public NativeQueryImplementor<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
super.setQueryFlushMode(queryFlushMode);
return this;
}
@Override
public NativeQueryImplementor<R> setFlushMode(FlushModeType flushModeType) {
super.setFlushMode( flushModeType );

View File

@ -14,6 +14,7 @@ import java.util.Map;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.Incubating;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -148,10 +149,13 @@ public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQu
@Override
NativeQueryImplementor<R> setHint(String hintName, Object value);
@Override
@Override @Deprecated(since = "7")
NativeQueryImplementor<R> setHibernateFlushMode(FlushMode flushMode);
@Override
NativeQueryImplementor<R> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override @Deprecated(since = "7")
NativeQueryImplementor<R> setFlushMode(FlushModeType flushMode);
@Override

View File

@ -14,6 +14,7 @@ import java.util.Map;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.query.BindableType;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.SelectionQuery;
@ -141,9 +142,12 @@ public interface SqmSelectionQuery<R> extends SqmQuery, SelectionQuery<R> {
@Override
SqmSelectionQuery<R> setProperties(@SuppressWarnings("rawtypes") Map bean);
@Override
@Override @Deprecated(since = "7")
SqmSelectionQuery<R> setHibernateFlushMode(FlushMode flushMode);
@Override
SqmSelectionQuery<R> setQueryFlushMode(QueryFlushMode queryFlushMode);
@Override
SqmSelectionQuery<R> setCacheMode(CacheMode cacheMode);

View File

@ -21,6 +21,7 @@ import java.util.function.Supplier;
import jakarta.persistence.EntityGraph;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -35,8 +36,6 @@ import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping;
import org.hibernate.metamodel.model.domain.EntityDomainType;
@ -123,7 +122,6 @@ import static org.hibernate.query.sqm.internal.SqmUtil.verifyIsNonSelectStatemen
public class QuerySqmImpl<R>
extends AbstractSqmSelectionQuery<R>
implements SqmQueryImplementor<R>, InterpretationsKeySource, DomainQueryExecutionContext {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( QuerySqmImpl.class );
private final String hql;
private SqmStatement<R> sqm;
@ -733,6 +731,12 @@ public class QuerySqmImpl<R>
return this;
}
@Override
public SqmQueryImplementor<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
super.setQueryFlushMode(queryFlushMode);
return this;
}
@Override
public SqmQueryImplementor<R> setFlushMode(FlushModeType flushMode) {
applyJpaFlushMode( flushMode );
@ -909,7 +913,7 @@ public class QuerySqmImpl<R>
isCacheable(),
getCacheRegion(),
getCacheMode(),
getHibernateFlushMode(),
getQueryOptions().getFlushMode(),
isReadOnly(),
getLockOptions(),
getTimeout(),
@ -929,7 +933,7 @@ public class QuerySqmImpl<R>
isCacheable(),
getCacheRegion(),
getCacheMode(),
getHibernateFlushMode(),
getQueryOptions().getFlushMode(),
isReadOnly(),
getLockOptions(),
getTimeout(),

View File

@ -24,6 +24,7 @@ import jakarta.persistence.TemporalType;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.LockMode;
import org.hibernate.ScrollMode;
import org.hibernate.engine.spi.LoadQueryInfluencers;
@ -551,6 +552,12 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
return this;
}
@Override
public SqmSelectionQuery<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
super.setQueryFlushMode(queryFlushMode);
return this;
}
@Override
public SqmSelectionQuery<R> setTimeout(int timeout) {
super.setTimeout( timeout );

View File

@ -29,8 +29,10 @@ import org.hibernate.query.KeyedResultList;
import org.hibernate.query.Order;
import org.hibernate.query.Page;
import org.hibernate.query.ParameterMetadata;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.sql.results.spi.ResultsConsumer;
@ -63,6 +65,16 @@ public abstract class DelegatingSqmSelectionQueryImplementor<R> implements SqmSe
return getDelegate().getHibernateFlushMode();
}
@Override
public QueryFlushMode getQueryFlushMode() {
return getDelegate().getQueryFlushMode();
}
@Override
public SqmSelectionQuery<R> setQueryFlushMode(QueryFlushMode queryFlushMode) {
return getDelegate().setQueryFlushMode( queryFlushMode );
}
@Override
public Integer getTimeout() {
return getDelegate().getTimeout();

View File

@ -25,7 +25,6 @@ import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* @author Yoann Rodiere
@ -103,22 +102,22 @@ public class NamedQueryFlushModeTest {
s.setHibernateFlushMode( FlushMode.MANUAL );
query = s.getNamedQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.COMMIT );
query = s.getNamedQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.COMMIT, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.AUTO );
query = s.getNamedQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.ALWAYS );
query = s.getNamedQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
}
);
@ -185,22 +184,22 @@ public class NamedQueryFlushModeTest {
s.setHibernateFlushMode( FlushMode.MANUAL );
query = s.getNamedNativeQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.COMMIT );
query = s.getNamedNativeQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.COMMIT, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.AUTO );
query = s.getNamedNativeQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.ALWAYS );
query = s.getNamedNativeQuery( queryName );
assertNull( query.getHibernateFlushMode() );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
}
);

View File

@ -0,0 +1,293 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.jpa.query;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.hibernate.FlushMode;
import org.hibernate.query.QueryFlushMode;
import org.hibernate.Session;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.annotations.NamedQuery;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Yoann Rodiere
*/
@JiraKey("HHH-12795")
@Jpa(annotatedClasses = {
NamedQueryQueryFlushModeTest.TestEntity.class
})
public class NamedQueryQueryFlushModeTest {
@Test
public void testNamedQueryWithFlushModeManual(EntityManagerFactoryScope scope) {
String queryName = "NamedQueryFlushModeManual";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
Query<?> query = s.getNamedQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
// JPA flush mode is an approximation
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
}
);
}
@Test
public void testNamedQueryWithFlushModeCommit(EntityManagerFactoryScope scope) {
String queryName = "NamedQueryFlushModeCommit";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
Query<?> query = s.getNamedQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
}
);
}
@Test
public void testNamedQueryWithFlushModeAuto(EntityManagerFactoryScope scope) {
String queryName = "NamedQueryFlushModeAuto";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
Query<?> query = s.getNamedQuery( queryName );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
}
);
}
@Test
public void testNamedQueryWithFlushModeAlways(EntityManagerFactoryScope scope) {
String queryName = "NamedQueryFlushModeAlways";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
Query<?> query = s.getNamedQuery( queryName );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
// JPA flush mode is an approximation
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
}
);
}
@Test
public void testNamedQueryWithFlushModePersistenceContext(EntityManagerFactoryScope scope) {
String queryName = "NamedQueryFlushModePersistenceContext";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
Query<?> query;
// A null Hibernate flush mode means we will use whatever mode is set on the session
// JPA doesn't allow null flush modes, so we expect some approximation of the flush mode to be returned
s.setHibernateFlushMode( FlushMode.MANUAL );
query = s.getNamedQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
assertEquals( QueryFlushMode.DEFAULT, query.getQueryFlushMode() );
s.setHibernateFlushMode( FlushMode.COMMIT );
query = s.getNamedQuery( queryName );
assertEquals( FlushMode.COMMIT, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
assertEquals( QueryFlushMode.DEFAULT, query.getQueryFlushMode() );
s.setHibernateFlushMode( FlushMode.AUTO );
query = s.getNamedQuery( queryName );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
assertEquals( QueryFlushMode.DEFAULT, query.getQueryFlushMode() );
s.setHibernateFlushMode( FlushMode.ALWAYS );
query = s.getNamedQuery( queryName );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
assertEquals( QueryFlushMode.DEFAULT, query.getQueryFlushMode() );
}
);
}
@Test
public void testNamedNativeQueryWithFlushModeManual(EntityManagerFactoryScope scope) {
String queryName = "NamedNativeQueryFlushModeManual";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
NativeQuery<?> query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( QueryFlushMode.NO_FLUSH, query.getQueryFlushMode() );
}
);
}
@Test
public void testNamedNativeQueryWithFlushModeCommit(EntityManagerFactoryScope scope) {
String queryName = "NamedNativeQueryFlushModeCommit";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
NativeQuery<?> query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( QueryFlushMode.NO_FLUSH, query.getQueryFlushMode() );
}
);
}
@Test
public void testNamedNativeQueryWithFlushModeAuto(EntityManagerFactoryScope scope) {
String queryName = "NamedNativeQueryFlushModeAuto";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
NativeQuery<?> query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( QueryFlushMode.DEFAULT, query.getQueryFlushMode() );
}
);
}
@Test
public void testNamedNativeQueryWithFlushModeAlways(EntityManagerFactoryScope scope) {
String queryName = "NamedNativeQueryFlushModeAlways";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
NativeQuery<?> query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
assertEquals( QueryFlushMode.FLUSH, query.getQueryFlushMode() );
}
);
}
@Test
public void testNamedNativeQueryWithFlushModePersistenceContext(EntityManagerFactoryScope scope) {
String queryName = "NamedNativeQueryFlushModePersistenceContext";
scope.inEntityManager(
entityManager -> {
Session s = entityManager.unwrap( Session.class );
NativeQuery<?> query;
// A null Hibernate flush mode means we will use whatever mode is set on the session
// JPA doesn't allow null flush modes, so we expect some approximation of the flush mode to be returned
s.setHibernateFlushMode( FlushMode.MANUAL );
query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.MANUAL, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.COMMIT );
query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.COMMIT, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.COMMIT, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.AUTO );
query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.AUTO, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
s.setHibernateFlushMode( FlushMode.ALWAYS );
query = s.getNamedNativeQuery( queryName );
assertEquals( FlushMode.ALWAYS, query.getHibernateFlushMode() );
assertEquals( jakarta.persistence.FlushModeType.AUTO, query.getFlushMode() );
}
);
}
@Entity(name = "TestEntity")
@NamedQuery(
name = "NamedQueryFlushModeManual",
query = "select e from TestEntity e where e.text = :text",
flush = QueryFlushMode.NO_FLUSH
)
@NamedQuery(
name = "NamedQueryFlushModeCommit",
query = "select e from TestEntity e where e.text = :text",
flush = QueryFlushMode.NO_FLUSH
)
@NamedQuery(
name = "NamedQueryFlushModeAuto",
query = "select e from TestEntity e where e.text = :text",
flush = QueryFlushMode.DEFAULT
)
@NamedQuery(
name = "NamedQueryFlushModeAlways",
query = "select e from TestEntity e where e.text = :text",
flush = QueryFlushMode.FLUSH
)
@NamedQuery(
name = "NamedQueryFlushModePersistenceContext",
query = "select e from TestEntity e where e.text = :text",
flush = QueryFlushMode.DEFAULT
)
@NamedNativeQuery(
name = "NamedNativeQueryFlushModeManual",
query = "select * from TestEntity e where e.text = :text",
resultClass = TestEntity.class,
flush = QueryFlushMode.NO_FLUSH
)
@NamedNativeQuery(
name = "NamedNativeQueryFlushModeCommit",
query = "select * from TestEntity e where e.text = :text",
resultClass = TestEntity.class,
flush = QueryFlushMode.NO_FLUSH
)
@NamedNativeQuery(
name = "NamedNativeQueryFlushModeAuto",
query = "select * from TestEntity e where e.text = :text",
resultClass = TestEntity.class,
flush = QueryFlushMode.DEFAULT
)
@NamedNativeQuery(
name = "NamedNativeQueryFlushModeAlways",
query = "select * from TestEntity e where e.text = :text",
resultClass = TestEntity.class,
flush = QueryFlushMode.FLUSH
)
@NamedNativeQuery(
name = "NamedNativeQueryFlushModePersistenceContext",
query = "select * from TestEntity e where e.text = :text",
resultClass = TestEntity.class,
flush = QueryFlushMode.DEFAULT
)
public static class TestEntity {
@Id
@GeneratedValue
private Long id;
private String text;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
}