HHH-16215 Composite primary key @IdClass attribute mapping is borrowed from the first OneToMany backref and cannot be set

This commit is contained in:
Andrea Boriero 2023-03-07 11:30:47 +01:00 committed by Christian Beikov
parent e1e0eb8968
commit c86d755d75
10 changed files with 53 additions and 69 deletions

View File

@ -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,

View File

@ -25,6 +25,8 @@ public interface AttributeMetadata {
boolean isUpdatable();
boolean isSelectable();
boolean isIncludedInDirtyChecking();
boolean isIncludedInOptimisticLocking();

View File

@ -348,6 +348,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
insertable,
updateable,
includeInOptimisticLocking,
true,
cascadeStyle
);

View File

@ -444,6 +444,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
insertable,
updateable,
includeInOptimisticLocking,
true,
cascadeStyle
);

View File

@ -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
);

View File

@ -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

View File

@ -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<Integer> 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(

View File

@ -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<Fetchable> 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();

View File

@ -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<T extends Statement> 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<Integer, List<SqlSelection>> sqlSelectionsToTrack = trackedFetchSelectionsForGroup.get( resolvedNavigablePath );
final int sqlSelectionStartIndexForFetch;
@ -7250,27 +7252,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> 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,

View File

@ -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;
}
}
}