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 3ba419f709..1e28f45fc0 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 @@ -688,6 +688,10 @@ public class LoaderSelectBuilder { LoaderSqlAstCreationState creationState, ImmutableFetchList.Builder fetches) { return (fetchable, isKeyFetchable) -> { + if ( !fetchable.isSelectable() ) { + return; + } + final NavigablePath fetchablePath; if ( isKeyFetchable ) { @@ -841,6 +845,7 @@ public class LoaderSelectBuilder { // For non-join fetches, we reset the currentBagRole and set it to the previous value in the finally block currentBagRole = null; } + final Fetch fetch = fetchParent.generateFetchableFetch( fetchable, fetchablePath, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMetadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMetadata.java index b40a6dda56..8fbc48f5b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMetadata.java @@ -25,6 +25,8 @@ public interface AttributeMetadata { boolean isUpdatable(); + boolean isSelectable(); + boolean isIncludedInDirtyChecking(); boolean isIncludedInOptimisticLocking(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java index bf5a3eb0d9..95872a49b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java @@ -348,6 +348,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType insertable, updateable, includeInOptimisticLocking, + true, cascadeStyle ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java index 5d290406c3..f49ffd84a1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java @@ -444,6 +444,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme insertable, updateable, includeInOptimisticLocking, + true, cascadeStyle ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index f3b1d748c0..ccf7ad2be1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -370,6 +370,7 @@ public class MappingModelCreationHelper { bootProperty.isInsertable(), bootProperty.isUpdateable(), bootProperty.isOptimisticLocked(), + bootProperty.isSelectable(), cascadeStyle ); } @@ -416,7 +417,7 @@ public class MappingModelCreationHelper { @SuppressWarnings("rawtypes") public static AttributeMetadata getAttributeMetadata(PropertyAccess propertyAccess) { - return new SimpleAttributeMetadata( propertyAccess, ImmutableMutabilityPlan.INSTANCE, false, true, false, false, null);// todo (6.0) : not sure if CascadeStyle=null is correct + return new SimpleAttributeMetadata( propertyAccess, ImmutableMutabilityPlan.INSTANCE, false, true, false, false, true, null);// todo (6.0) : not sure if CascadeStyle=null is correct } @SuppressWarnings("rawtypes") @@ -605,6 +606,7 @@ public class MappingModelCreationHelper { bootProperty.isInsertable(), bootProperty.isUpdateable(), bootProperty.isOptimisticLocked(), + bootProperty.isSelectable(), cascadeStyle ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleAttributeMetadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleAttributeMetadata.java index e18778fc1b..fc6260d50f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleAttributeMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleAttributeMetadata.java @@ -21,6 +21,7 @@ public final class SimpleAttributeMetadata implements AttributeMetadata { private final boolean nullable; private final boolean insertable; private final boolean updateable; + private final boolean selectable; private final boolean includeInOptimisticLocking; private final CascadeStyle cascadeStyle; @@ -36,14 +37,19 @@ public final class SimpleAttributeMetadata implements AttributeMetadata { value.isNullable(), bootProperty.isInsertable(), bootProperty.isUpdateable(), - bootProperty.isOptimisticLocked() + bootProperty.isOptimisticLocked(), + bootProperty.isSelectable() ); } public SimpleAttributeMetadata( PropertyAccess propertyAccess, MutabilityPlan mutabilityPlan, - boolean nullable, boolean insertable, boolean updateable, boolean includeInOptimisticLocking) { + boolean nullable, + boolean insertable, + boolean updateable, + boolean includeInOptimisticLocking, + boolean selectable) { this( propertyAccess, mutabilityPlan, @@ -51,6 +57,7 @@ public final class SimpleAttributeMetadata implements AttributeMetadata { insertable, updateable, includeInOptimisticLocking, + selectable, CascadeStyles.NONE // default - but beware of comment on AttributeMetadata#getCascadeStyle having a TODO ); } @@ -62,12 +69,14 @@ public final class SimpleAttributeMetadata implements AttributeMetadata { boolean insertable, boolean updateable, boolean includeInOptimisticLocking, + boolean selectable, CascadeStyle cascadeStyle) { this.propertyAccess = propertyAccess; this.mutabilityPlan = mutabilityPlan; this.nullable = nullable; this.insertable = insertable; this.updateable = updateable; + this.selectable = selectable; this.includeInOptimisticLocking = includeInOptimisticLocking; this.cascadeStyle = cascadeStyle; } @@ -97,6 +106,11 @@ public final class SimpleAttributeMetadata implements AttributeMetadata { return updateable; } + @Override + public boolean isSelectable(){ + return selectable; + } + @Override public boolean isIncludedInDirtyChecking() { // todo (6.0) : do not believe this is correct 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 decf72815a..4c877a926d 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 @@ -255,7 +255,6 @@ import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.FetchableContainer; -import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode; import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.SqlSelectionImpl; @@ -370,7 +369,6 @@ public abstract class AbstractEntityPersister private final String[][] propertyColumnWriters; private final boolean[][] propertyColumnUpdateable; private final boolean[][] propertyColumnInsertable; - private final boolean[] propertySelectable; private final List lobProperties; @@ -619,7 +617,6 @@ public abstract class AbstractEntityPersister propertyColumnNames = new String[hydrateSpan][]; propertyColumnFormulaTemplates = new String[hydrateSpan][]; propertyColumnWriters = new String[hydrateSpan][]; - propertySelectable = new boolean[hydrateSpan]; propertyColumnUpdateable = new boolean[hydrateSpan][]; propertyColumnInsertable = new boolean[hydrateSpan][]; @@ -691,8 +688,6 @@ public abstract class AbstractEntityPersister propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability(); propertyColumnInsertable[i] = prop.getValue().getColumnInsertability(); - propertySelectable[i] = prop.isSelectable(); - if ( prop.isLob() && dialect.forceLobAsLastValue() ) { lobPropertiesLocalCollector.add( i ); } @@ -1813,7 +1808,7 @@ public abstract class AbstractEntityPersister throw new AssertionFailure("fetchTiming was null"); } - if ( isSelectable( fetchParent, fetchable ) ) { + if ( fetchable.isSelectable() ) { final Fetch fetch = fetchParent.generateFetchableFetch( fetchable, fetchParent.resolveNavigablePath( fetchable ), @@ -1830,37 +1825,12 @@ public abstract class AbstractEntityPersister return fetches.build(); } + /** + * @deprecated use {@link Fetchable#isSelectable()} instead. + */ + @Deprecated public boolean isSelectable(FetchParent fetchParent, Fetchable fetchable) { - if ( fetchParent instanceof EmbeddableResultGraphNode ) { - return true; - } - else { - final AttributeMapping attributeMapping = fetchable.asAttributeMapping(); - if ( attributeMapping != null ) { - final int propertyNumber = attributeMapping.getStateArrayPosition(); - if ( propertyNumber < propertySelectable.length ) { - return propertySelectable[propertyNumber]; - } - else { - final ManagedMappingType declaringType = attributeMapping.getDeclaringType(); - // try to check select-ability from the declaring type - if ( declaringType != this ) { - assert declaringType instanceof AbstractEntityPersister; - final AbstractEntityPersister subPersister = (AbstractEntityPersister) declaringType; - return subPersister.propertySelectable[propertyNumber]; - } - else { - throw new IllegalArgumentException( - "Unrecognized fetchable [" + fetchable.getFetchableName() + "] at index " - + propertyNumber + " for entity [" + getEntityName() + "]" - ); - } - } - } - else { - return true; - } - } + return fetchable.isSelectable(); } @Override @@ -4162,7 +4132,7 @@ public abstract class AbstractEntityPersister @Override public boolean isPropertySelectable(int propertyNumber) { - return propertySelectable[propertyNumber]; + return getAttributeMapping( propertyNumber ).getAttributeMetadata().isSelectable(); } @Override @@ -5424,7 +5394,8 @@ public abstract class AbstractEntityPersister bootProperty.isOptional(), bootProperty.isInsertable(), bootProperty.isUpdateable(), - bootProperty.isOptimisticLocked() + bootProperty.isOptimisticLocked(), + bootProperty.isSelectable() ); return new DiscriminatedAssociationAttributeMapping( diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java index 586494f82f..385457a46f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java @@ -31,7 +31,6 @@ import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart; import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl; import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping; -import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.spi.EntityIdentifierNavigablePath; import org.hibernate.spi.NavigablePath; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; @@ -460,9 +459,7 @@ public class DomainResultCreationStateImpl private Consumer createFetchableConsumer(FetchParent fetchParent, ImmutableFetchList.Builder fetches) { return fetchable -> { - final FetchableContainer parentMappingType = fetchParent.getReferencedMappingContainer(); - if ( parentMappingType instanceof AbstractEntityPersister - && !( ( (AbstractEntityPersister) parentMappingType ).isSelectable( fetchParent, fetchable ) ) ) { + if ( !fetchable.isSelectable() ) { return; } final String fetchableName = fetchable.getFetchableName(); 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 c4a110f27c..26060b0605 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 @@ -102,7 +102,6 @@ import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource; import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl; import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.SingleTableEntityPersister; import org.hibernate.query.BindableType; import org.hibernate.query.QueryLogging; @@ -7130,6 +7129,9 @@ public abstract class BaseSqmToSqlAstConverter extends Base } private Fetch createFetch(FetchParent fetchParent, Fetchable fetchable, Boolean isKeyFetchable) { + if ( !fetchable.isSelectable() ) { + return null; + } final NavigablePath resolvedNavigablePath = fetchParent.resolveNavigablePath( fetchable ); final Map.Entry> sqlSelectionsToTrack = trackedFetchSelectionsForGroup.get( resolvedNavigablePath ); final int sqlSelectionStartIndexForFetch; @@ -7250,27 +7252,6 @@ public abstract class BaseSqmToSqlAstConverter extends Base ); lhs.addTableGroupJoin( tableGroupJoin ); -// if ( fetchable instanceof PluralAttributeMapping ) { -// // apply restrictions -// ( (Restrictable) fetchable ).applyBaseRestrictions( -// tableGroupJoin::applyPredicate, -// tableGroupJoin.getJoinedGroup(), -// true, -// loadQueryInfluencers.getEnabledFilters(), -// null, -// getSqlAstCreationState() -// ); -// -// ( (PluralAttributeMapping) fetchable ).applyBaseManyToManyRestrictions( -// tableGroupJoin::applyPredicate, -// tableGroupJoin.getJoinedGroup(), -// true, -// loadQueryInfluencers.getEnabledFilters(), -// null, -// getSqlAstCreationState() -// ); -// } - // and return the joined group return tableGroupJoin.getJoinedGroup(); } @@ -7426,11 +7407,11 @@ public abstract class BaseSqmToSqlAstConverter extends Base // Base restrictions have already been applied if this is an explicit fetch if ( !explicitFetch ) { - final Joinable joinable = pluralAttributeMapping + final Restrictable restrictable = pluralAttributeMapping .getCollectionDescriptor() .getCollectionType() .getAssociatedJoinable( getCreationContext().getSessionFactory() ); - joinable.applyBaseRestrictions( + restrictable.applyBaseRestrictions( (predicate) -> addCollectionFilterPredicate( tableGroup.getNavigablePath(), predicate ), tableGroup, true, diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/Fetchable.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/Fetchable.java index d98ecb40f3..6597eafa40 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/Fetchable.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/Fetchable.java @@ -89,4 +89,14 @@ public interface Fetchable extends ModelPart { default AttributeMapping asAttributeMapping() { return null; } + + default boolean isSelectable() { + final AttributeMapping attributeMapping = asAttributeMapping(); + if ( attributeMapping != null ) { + return attributeMapping.getAttributeMetadata().isSelectable(); + } + else { + return true; + } + } }