From c636c83d7e9f7f0eb6ce1c3661805742a6dbbed4 Mon Sep 17 00:00:00 2001 From: Gavin Date: Tue, 23 May 2023 09:12:59 +0200 Subject: [PATCH] HHH-16651 cleaner separation of "fetch method" vs "fetch timing" --- .../org/hibernate/annotations/FetchMode.java | 18 ++-- .../hibernate/annotations/FetchProfile.java | 20 +++- .../boot/model/internal/AnnotationBinder.java | 8 +- .../internal/FetchOverrideSecondPass.java | 10 +- .../org/hibernate/engine/FetchTiming.java | 15 ++- .../org/hibernate/engine/profile/Fetch.java | 91 ++++++++++++++++++- .../engine/profile/FetchProfile.java | 4 +- .../internal/FetchProfileAffectee.java | 4 +- .../engine/spi/LoadQueryInfluencers.java | 6 +- .../internal/FetchProfileHelper.java | 16 ++-- .../ast/internal/LoaderSelectBuilder.java | 5 +- .../org/hibernate/mapping/FetchProfile.java | 61 ++++++++++++- .../internal/PluralAttributeMappingImpl.java | 4 +- .../AbstractCollectionPersister.java | 12 +-- .../entity/AbstractEntityPersister.java | 5 - .../sqm/sql/BaseSqmToSqlAstConverter.java | 16 ++-- 16 files changed, 228 insertions(+), 67 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java b/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java index 34e936385e..276775edc9 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java @@ -7,7 +7,7 @@ package org.hibernate.annotations; /** - * Enumerates strategies for fetching an association from the database. + * Enumerates methods for fetching an association from the database. *

* The JPA-defined {@link jakarta.persistence.FetchType} enumerates the * possibilities for when an association might be fetched. This @@ -46,7 +46,7 @@ public enum FetchMode { * when it is almost certain that the associated data will be * available in the second-level cache. */ - SELECT( org.hibernate.FetchMode.SELECT ), + SELECT, /** * Use an outer join to load all instances of the related entity @@ -62,7 +62,7 @@ public enum FetchMode { * since the associated data is retrieved as part of the initial * query. */ - JOIN( org.hibernate.FetchMode.JOIN ), + JOIN, /** * Use a secondary select with a subselect that re-executes an @@ -84,15 +84,11 @@ public enum FetchMode { * re-execution of the initial query within a SQL subselect. * */ - SUBSELECT( org.hibernate.FetchMode.SELECT ); - - private final org.hibernate.FetchMode hibernateFetchMode; - - FetchMode(org.hibernate.FetchMode hibernateFetchMode) { - this.hibernateFetchMode = hibernateFetchMode; - } + SUBSELECT; public org.hibernate.FetchMode getHibernateFetchMode() { - return hibernateFetchMode; + return this == JOIN + ? org.hibernate.FetchMode.JOIN + : org.hibernate.FetchMode.SELECT; } } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java index 4ae809a66f..c17ae169ba 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java @@ -6,10 +6,13 @@ */ package org.hibernate.annotations; +import jakarta.persistence.FetchType; + import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static jakarta.persistence.FetchType.EAGER; import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -91,8 +94,11 @@ public @interface FetchProfile { FetchOverride[] fetchOverrides() default {}; /** - * Overrides the fetching strategy pf a particular association - * in the named fetch profile being defined. + * Overrides the fetching strategy of a particular association in + * the named fetch profile being defined. If {@link #mode} and + * {@link #fetch} are both unspecified, the strategy defaults to + * {@linkplain FetchType#EAGER eager} {@linkplain FetchMode#JOIN join} + * fetching. */ @Target({ TYPE, PACKAGE }) @Retention(RUNTIME) @@ -110,9 +116,15 @@ public @interface FetchProfile { String association(); /** - * The {@linkplain FetchMode fetching strategy} to apply to - * the association in the fetch profile being defined. + * The {@linkplain FetchMode method} used for fetching the + * association in the fetch profile being defined. */ FetchMode mode() default JOIN; + + /** + * The {@link FetchType timing} of association fetching in + * the fetch profile being defined. + */ + FetchType fetch() default EAGER; } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java index ced3a55603..5f64d57856 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import jakarta.persistence.FetchType; import org.hibernate.AnnotationException; import org.hibernate.MappingException; import org.hibernate.annotations.CollectionTypeRegistration; @@ -22,6 +23,7 @@ import org.hibernate.annotations.ConverterRegistration; import org.hibernate.annotations.ConverterRegistrations; import org.hibernate.annotations.EmbeddableInstantiatorRegistration; import org.hibernate.annotations.EmbeddableInstantiatorRegistrations; +import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchProfile; import org.hibernate.annotations.FetchProfile.FetchOverride; import org.hibernate.annotations.FetchProfiles; @@ -852,7 +854,11 @@ public final class AnnotationBinder { final String name = fetchProfile.name(); if ( reuseOrCreateFetchProfile( context, name ) ) { for ( FetchOverride fetch : fetchProfile.fetchOverrides() ) { - // TODO: validate which modes are valid where + if ( fetch.fetch() == FetchType.LAZY && fetch.mode() == FetchMode.JOIN ) { + throw new AnnotationException( "Fetch profile '" + name + + "' has a '@FetchOverride' with 'fetch=LAZY' and 'mode=JOIN'" + + " (join fetching is eager by nature)"); + } context.getMetadataCollector() .addSecondPass( new FetchOverrideSecondPass( name, fetch, context ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FetchOverrideSecondPass.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FetchOverrideSecondPass.java index 3f40bd5594..6f1359ae4a 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FetchOverrideSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/FetchOverrideSecondPass.java @@ -13,7 +13,6 @@ import org.hibernate.boot.spi.SecondPass; import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.PersistentClass; -import java.util.Locale; import java.util.Map; /** @@ -43,9 +42,12 @@ public class FetchOverrideSecondPass implements SecondPass { final FetchProfile profile = buildingContext.getMetadataCollector().getFetchProfile( fetchProfileName ); // we already know that the FetchProfile exists and is good to use profile.addFetch( - fetch.entity().getName(), - fetch.association(), - fetch.mode().toString().toLowerCase(Locale.ROOT) + new FetchProfile.Fetch( + fetch.entity().getName(), + fetch.association(), + fetch.mode(), + fetch.fetch() + ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/FetchTiming.java b/hibernate-core/src/main/java/org/hibernate/engine/FetchTiming.java index 763d7a9272..e4166c91b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/FetchTiming.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/FetchTiming.java @@ -6,6 +6,8 @@ */ package org.hibernate.engine; +import jakarta.persistence.FetchType; + /** * Enumeration of values describing when fetching should occur. * @@ -20,5 +22,16 @@ public enum FetchTiming { /** * Performing fetching later, when needed. Also called lazy fetching. */ - DELAYED + DELAYED; + + public static FetchTiming forType(FetchType type) { + switch ( type ) { + case EAGER: + return IMMEDIATE; + case LAZY: + return DELAYED; + default: + throw new IllegalArgumentException( "Unknown FetchType" ); + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java index cd1d1cc4ea..9b4db11ab6 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/Fetch.java @@ -6,8 +6,15 @@ */ package org.hibernate.engine.profile; +import org.hibernate.AssertionFailure; +import org.hibernate.annotations.FetchMode; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; + import java.util.Locale; +import static org.hibernate.engine.FetchTiming.IMMEDIATE; + /** * Models an individual fetch override within a {@link FetchProfile}. * @@ -15,17 +22,34 @@ import java.util.Locale; */ public class Fetch { private final Association association; - private final Style style; + private final FetchStyle method; + private final FetchTiming timing; /** * Constructs a {@link Fetch}. * * @param association The association to be fetched * @param style How to fetch it + * + * @deprecated use {@link #Fetch(Association,FetchStyle,FetchTiming)} */ + @Deprecated(forRemoval = true) public Fetch(Association association, Style style) { this.association = association; - this.style = style; + this.method = style.toFetchStyle(); + this.timing = IMMEDIATE; + } + + /** + * Constructs a {@link Fetch}. + * + * @param association The association to be fetched + * @param method How to fetch it + */ + public Fetch(Association association, FetchStyle method, FetchTiming timing) { + this.association = association; + this.method = method; + this.timing = timing; } /** @@ -37,14 +61,34 @@ public class Fetch { /** * The fetch style applied to the association. + * + * @deprecated use {@link #getMethod()} */ + @Deprecated(forRemoval = true) public Style getStyle() { - return style; + return Style.fromFetchStyle( method ); + } + + /** + * The fetch method to be applied to the association. + */ + public FetchStyle getMethod() { + return method; + } + + /** + * The fetch timing to be applied to the association. + */ + public FetchTiming getTiming() { + return timing; } /** * The type or style of fetch. + * + * @deprecated Use {@link FetchStyle} */ + @Deprecated(forRemoval = true) public enum Style { /** * Fetch via a join @@ -59,6 +103,32 @@ public class Fetch { */ SUBSELECT; + public FetchStyle toFetchStyle() { + switch (this) { + case SELECT: + return FetchStyle.SELECT; + case SUBSELECT: + return FetchStyle.SUBSELECT; + case JOIN: + return FetchStyle.JOIN; + default: + throw new AssertionFailure("Unknown Fetch.Style"); + } + } + + static Style fromFetchStyle(FetchStyle fetchStyle) { + switch (fetchStyle) { + case SELECT: + return SELECT; + case SUBSELECT: + return SUBSELECT; + case JOIN: + return JOIN; + default: + throw new IllegalArgumentException("Unhandled FetchStyle"); + } + } + @Override public String toString() { return name().toLowerCase(Locale.ROOT); @@ -79,10 +149,23 @@ public class Fetch { } return JOIN; } + + public static Style forMethod(FetchMode fetchMode) { + switch ( fetchMode ) { + case JOIN: + return JOIN; + case SELECT: + return SELECT; + case SUBSELECT: + return SUBSELECT; + default: + throw new IllegalArgumentException( "Unknown FetchMode" ); + } + } } @Override public String toString() { - return "Fetch[" + style + "{" + association.getRole() + "}]"; + return "Fetch[" + method + "{" + association.getRole() + "}]"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java index 399f88a256..e10860d51e 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java @@ -15,6 +15,8 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.BagType; import org.hibernate.type.Type; +import static org.hibernate.engine.FetchStyle.JOIN; + /** * The runtime representation of a Hibernate * {@linkplain org.hibernate.annotations.FetchProfile fetch profile} @@ -97,7 +99,7 @@ public class FetchProfile { // couple of things for which to account in the case of collection // join fetches - if ( Fetch.Style.JOIN == fetch.getStyle() ) { + if ( fetch.getMethod() == JOIN ) { // first, if this is a bag we need to ignore it if we previously // processed collection join fetches if ( associationType instanceof BagType ) { diff --git a/hibernate-core/src/main/java/org/hibernate/engine/profile/internal/FetchProfileAffectee.java b/hibernate-core/src/main/java/org/hibernate/engine/profile/internal/FetchProfileAffectee.java index 9667c0a2a6..f771f0e48f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/profile/internal/FetchProfileAffectee.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/profile/internal/FetchProfileAffectee.java @@ -6,8 +6,6 @@ */ package org.hibernate.engine.profile.internal; -import org.hibernate.engine.profile.Fetch; - /** * Commonality between entities and collections as something that can be affected by fetch profiles. * @@ -17,5 +15,5 @@ public interface FetchProfileAffectee { /** * Register the profile name with the entity/collection */ - void registerAffectingFetchProfile(String fetchProfileName, Fetch.Style fetchStyle); + void registerAffectingFetchProfile(String fetchProfileName); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/LoadQueryInfluencers.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/LoadQueryInfluencers.java index 7710ab5e28..679ba4c234 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/LoadQueryInfluencers.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/LoadQueryInfluencers.java @@ -26,7 +26,7 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import static java.util.Collections.emptySet; -import static org.hibernate.engine.profile.Fetch.Style.SUBSELECT; +import static org.hibernate.engine.FetchStyle.SUBSELECT; /** * Centralize all options which can influence the SQL query needed to load an @@ -318,7 +318,7 @@ public class LoadQueryInfluencers implements Serializable { final FetchProfile fetchProfile = sessionFactory.getFetchProfile( profile ); if ( fetchProfile != null ) { final Fetch fetch = fetchProfile.getFetchByRole( persister.getRole() ); - if ( fetch != null && fetch.getStyle() == SUBSELECT ) { + if ( fetch != null && fetch.getMethod() == SUBSELECT) { return true; } } @@ -347,7 +347,7 @@ public class LoadQueryInfluencers implements Serializable { final FetchProfile fetchProfile = sessionFactory.getFetchProfile( profile ); for ( Fetch fetch : fetchProfile.getFetches().values() ) { // TODO: check that it's relevant to this persister?? - if ( fetch.getStyle() == SUBSELECT ) { + if ( fetch.getMethod() == SUBSELECT ) { return true; } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java index 1ffe879cf2..a5d4cba794 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/FetchProfileHelper.java @@ -8,6 +8,8 @@ package org.hibernate.internal; import org.hibernate.HibernateException; import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; import org.hibernate.engine.profile.Association; import org.hibernate.engine.profile.Fetch; import org.hibernate.engine.profile.FetchProfile; @@ -44,24 +46,24 @@ public class FetchProfileHelper { org.hibernate.mapping.FetchProfile mappingProfile) { final String profileName = mappingProfile.getName(); final FetchProfile fetchProfile = new FetchProfile( profileName ); - for ( org.hibernate.mapping.FetchProfile.Fetch mappingFetch : mappingProfile.getFetches() ) { // resolve the persister owning the fetch final EntityPersister owner = getEntityPersister( mappingMetamodel, fetchProfile, mappingFetch ); - ( (FetchProfileAffectee) owner ).registerAffectingFetchProfile( profileName, null ); + ( (FetchProfileAffectee) owner ).registerAffectingFetchProfile( profileName); final Association association = new Association( owner, mappingFetch.getAssociation() ); - final Fetch.Style fetchStyle = Fetch.Style.parse( mappingFetch.getStyle() ); + final FetchStyle fetchStyle = Fetch.Style.forMethod( mappingFetch.getMethod() ).toFetchStyle(); + final FetchTiming fetchTiming = FetchTiming.forType( mappingFetch.getType() ); // validate the specified association fetch final ModelPart fetchablePart = owner.findByPath( association.getAssociationPath() ); validateFetchablePart( fetchablePart, profileName, association ); if ( fetchablePart instanceof FetchProfileAffectee ) { - ( (FetchProfileAffectee) fetchablePart ).registerAffectingFetchProfile( profileName, fetchStyle ); + ( (FetchProfileAffectee) fetchablePart ).registerAffectingFetchProfile( profileName ); } // then register the association with the FetchProfile - fetchProfile.addFetch( new Fetch( association, fetchStyle ) ); + fetchProfile.addFetch( new Fetch( association, fetchStyle, fetchTiming ) ); } return fetchProfile; } @@ -86,7 +88,7 @@ public class FetchProfileHelper { private static boolean isAssociation(ModelPart fetchablePart) { return fetchablePart instanceof EntityValuedModelPart - || fetchablePart instanceof PluralAttributeMapping; + || fetchablePart instanceof PluralAttributeMapping; } private static EntityPersister getEntityPersister( @@ -95,7 +97,7 @@ public class FetchProfileHelper { org.hibernate.mapping.FetchProfile.Fetch mappingFetch) { final String entityName = mappingMetamodel.getImportedName( mappingFetch.getEntity() ); if ( entityName != null ) { - EntityPersister persister = mappingMetamodel.getEntityDescriptor( entityName ); + final EntityPersister persister = mappingMetamodel.getEntityDescriptor( entityName ); if ( persister != null ) { return persister; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index b5e17f9814..41c926ca31 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -88,7 +88,6 @@ import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl; import org.jboss.logging.Logger; import static java.util.Collections.singletonList; -import static org.hibernate.engine.profile.Fetch.Style; import static org.hibernate.query.results.ResultsHelper.attributeName; /** @@ -878,8 +877,8 @@ public class LoaderSelectBuilder { final org.hibernate.engine.profile.Fetch profileFetch = enabledFetchProfile.getFetchByRole( fetchableRole ); if ( profileFetch != null ) { - fetchTiming = FetchTiming.IMMEDIATE; - joined = joined || profileFetch.getStyle() == Style.JOIN; + fetchTiming = profileFetch.getTiming(); + joined = joined || profileFetch.getMethod() == FetchStyle.JOIN; explicitFetch = shouldExplicitFetch( maximumFetchDepth, fetchable, creationState ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/mapping/FetchProfile.java index dcdd88f70c..185e1176cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/FetchProfile.java @@ -5,7 +5,14 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.mapping; + +import jakarta.persistence.FetchType; +import org.hibernate.annotations.FetchMode; + import java.util.LinkedHashSet; +import java.util.Locale; + +import static jakarta.persistence.FetchType.EAGER; /** * A mapping model object representing a {@link org.hibernate.annotations.FetchProfile}. @@ -63,9 +70,19 @@ public class FetchProfile { * @param entity The entity which contains the association to be fetched * @param association The association to fetch * @param style The style of fetch to apply + * + * @deprecated use {@link #addFetch(Fetch)} */ + @Deprecated(forRemoval = true) public void addFetch(String entity, String association, String style) { - fetches.add( new Fetch( entity, association, style ) ); + addFetch( new Fetch( entity, association, style ) ); + } + + /** + * Adds a fetch to this profile. + */ + public void addFetch(Fetch fetch) { + fetches.add( fetch ); } @Override @@ -89,17 +106,39 @@ public class FetchProfile { /** - * Defines an individual association fetch within the given profile. + * An individual association fetch within the given profile. */ public static class Fetch { private final String entity; private final String association; - private final String style; + private final FetchMode method; + private final FetchType type; + public Fetch(String entity, String association, FetchMode method, FetchType type) { + this.entity = entity; + this.association = association; + this.method = method; + this.type = type; + } + + /** + * @deprecated use {@link FetchProfile.Fetch#Fetch(String,String,FetchMode,FetchType)} + */ + @Deprecated(forRemoval = true) public Fetch(String entity, String association, String style) { this.entity = entity; this.association = association; - this.style = style; + this.method = fetchMode( style ); + this.type = EAGER; + } + + private FetchMode fetchMode(String style) { + for ( FetchMode mode: FetchMode.values() ) { + if ( mode.name().equalsIgnoreCase( style ) ) { + return mode; + } + } + throw new IllegalArgumentException( "Unknown FetchMode: " + style ); } public String getEntity() { @@ -110,8 +149,20 @@ public class FetchProfile { return association; } + /** + * @deprecated use {@link #getMethod()} + */ + @Deprecated(forRemoval = true) public String getStyle() { - return style; + return method.toString().toLowerCase(Locale.ROOT); + } + + public FetchMode getMethod() { + return method; + } + + public FetchType getType() { + return type; } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java index 4cf09c99c3..a3ab35553c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java @@ -901,9 +901,9 @@ public class PluralAttributeMappingImpl } @Override - public void registerAffectingFetchProfile(String fetchProfileName, org.hibernate.engine.profile.Fetch.Style fetchStyle) { + public void registerAffectingFetchProfile(String fetchProfileName) { if ( collectionDescriptor instanceof FetchProfileAffectee ) { - ( (FetchProfileAffectee) collectionDescriptor ).registerAffectingFetchProfile( fetchProfileName, fetchStyle ); + ( (FetchProfileAffectee) collectionDescriptor ).registerAffectingFetchProfile( fetchProfileName); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index ca962c4493..99d06a9497 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -30,7 +30,6 @@ import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; -import org.hibernate.engine.profile.Fetch; import org.hibernate.engine.profile.internal.FetchProfileAffectee; import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.LoadQueryInfluencers; @@ -127,6 +126,7 @@ import java.sql.SQLException; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -232,7 +232,7 @@ public abstract class AbstractCollectionPersister private CollectionElementLoaderByIndex collectionElementLoaderByIndex; private PluralAttributeMapping attributeMapping; - private volatile Map affectingFetchProfiles; + private volatile Set affectingFetchProfiles; @Deprecated(since = "6.0") @@ -1556,17 +1556,17 @@ public abstract class AbstractCollectionPersister } @Override - public void registerAffectingFetchProfile(String fetchProfileName, Fetch.Style fetchStyle) { + public void registerAffectingFetchProfile(String fetchProfileName) { if ( affectingFetchProfiles == null ) { - affectingFetchProfiles = new HashMap<>(); + affectingFetchProfiles = new HashSet<>(); } - affectingFetchProfiles.put( fetchProfileName, fetchStyle ); + affectingFetchProfiles.add( fetchProfileName ); } @Override public boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers) { if ( affectingFetchProfiles != null && influencers.hasEnabledFetchProfiles() ) { - for ( String profileName : affectingFetchProfiles.keySet() ) { + for ( String profileName : affectingFetchProfiles ) { if ( influencers.isFetchProfileEnabled( profileName ) ) { return true; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index e6cb55a4cb..7f2404867b 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -3518,11 +3518,6 @@ public abstract class AbstractEntityPersister affectingFetchProfileNames.add( fetchProfileName ); } - @Override - public void registerAffectingFetchProfile(String fetchProfileName, org.hibernate.engine.profile.Fetch.Style fetchStyle) { - registerAffectingFetchProfile( fetchProfileName ); - } - @Override public boolean isAffectedByEntityGraph(LoadQueryInfluencers loadQueryInfluencers) { final RootGraphImplementor graph = loadQueryInfluencers.getEffectiveEntityGraph().getGraph(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 89e47c9d1f..61e7e262b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -38,6 +38,7 @@ import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.function.TimestampaddFunction; import org.hibernate.dialect.function.TimestampdiffFunction; +import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.profile.FetchProfile; import org.hibernate.engine.spi.LoadQueryInfluencers; @@ -7643,20 +7644,21 @@ public abstract class BaseSqmToSqlAstConverter extends Base final FetchProfile enabledFetchProfile = getCreationContext() .getSessionFactory() .getFetchProfile( enabledFetchProfileName ); - final org.hibernate.engine.profile.Fetch profileFetch = enabledFetchProfile.getFetchByRole( - fetchableRole ); + final org.hibernate.engine.profile.Fetch profileFetch = + enabledFetchProfile.getFetchByRole( fetchableRole ); if ( profileFetch != null ) { - fetchTiming = FetchTiming.IMMEDIATE; - joined = joined || profileFetch.getStyle() == org.hibernate.engine.profile.Fetch.Style.JOIN; + fetchTiming = profileFetch.getTiming(); + joined = joined || profileFetch.getMethod() == FetchStyle.JOIN; if ( shouldExplicitFetch( maxDepth, fetchable ) ) { explicitFetch = true; } if ( currentBagRole != null && fetchable instanceof PluralAttributeMapping ) { - final CollectionClassification collectionClassification = ( (PluralAttributeMapping) fetchable ).getMappedType() - .getCollectionSemantics() - .getCollectionClassification(); + final CollectionClassification collectionClassification = + ( (PluralAttributeMapping) fetchable ).getMappedType() + .getCollectionSemantics() + .getCollectionClassification(); if ( collectionClassification == CollectionClassification.BAG ) { // To avoid a MultipleBagFetchException due to fetch profiles in a circular model, // we skip join fetching in case we encounter an existing bag role