HHH-15811 Avoid secondary super-type cache pollution when casting to AttributeMapping

This commit is contained in:
Sanne Grinovero 2022-12-03 22:15:17 +00:00 committed by Sanne Grinovero
parent a7c3455274
commit d383042229
8 changed files with 35 additions and 15 deletions

View File

@ -756,7 +756,7 @@ else if ( loadQueryInfluencers.hasEnabledFetchProfiles() ) {
} }
} }
else if ( loadQueryInfluencers.getEnabledCascadingFetchProfile() != null ) { else if ( loadQueryInfluencers.getEnabledCascadingFetchProfile() != null ) {
final CascadeStyle cascadeStyle = ( (AttributeMapping) fetchable ).getAttributeMetadataAccess() final CascadeStyle cascadeStyle = fetchable.asAttributeMapping().getAttributeMetadataAccess()
.resolveAttributeMetadata( fetchable.findContainingEntityMapping() ) .resolveAttributeMetadata( fetchable.findContainingEntityMapping() )
.getCascadeStyle(); .getCascadeStyle();
final CascadingAction cascadingAction = loadQueryInfluencers.getEnabledCascadingFetchProfile() final CascadingAction cascadingAction = loadQueryInfluencers.getEnabledCascadingFetchProfile()

View File

@ -86,4 +86,10 @@ default int compare(Object value1, Object value2) {
//noinspection unchecked,rawtypes //noinspection unchecked,rawtypes
return ( (JavaType) getJavaType() ).getComparator().compare( value1, value2 ); return ( (JavaType) getJavaType() ).getComparator().compare( value1, value2 );
} }
@Override //Overrides multiple interfaces!
default AttributeMapping asAttributeMapping() {
return this;
}
} }

View File

@ -97,6 +97,10 @@ default int forEachSelectable(int offset, SelectableConsumer consumer) {
return 0; return 0;
} }
default AttributeMapping asAttributeMapping() {
return null;
}
@FunctionalInterface @FunctionalInterface
interface JdbcValueConsumer { interface JdbcValueConsumer {
void consume(Object value, SelectableMapping jdbcValueMapping); void consume(Object value, SelectableMapping jdbcValueMapping);

View File

@ -1859,8 +1859,10 @@ private boolean isSelectable(FetchParent fetchParent, Fetchable fetchable) {
if ( fetchParent instanceof EmbeddableResultGraphNode ) { if ( fetchParent instanceof EmbeddableResultGraphNode ) {
return true; return true;
} }
else if ( fetchable instanceof AttributeMapping ) { else {
final int propertyNumber = ( (AttributeMapping) fetchable ).getStateArrayPosition(); final AttributeMapping attributeMapping = fetchable.asAttributeMapping();
if ( attributeMapping != null ) {
final int propertyNumber = attributeMapping.getStateArrayPosition();
// final int tableNumber = getSubclassPropertyTableNumber( propertyNumber ); // final int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
// return !isSubclassTableSequentialSelect( tableNumber ) && propertySelectable[propertyNumber]; // return !isSubclassTableSequentialSelect( tableNumber ) && propertySelectable[propertyNumber];
return propertySelectable[propertyNumber]; return propertySelectable[propertyNumber];
@ -1869,6 +1871,7 @@ else if ( fetchable instanceof AttributeMapping ) {
return true; return true;
} }
} }
}
@Override @Override
public String[] getIdentifierAliases(String suffix) { public String[] getIdentifierAliases(String suffix) {
@ -4187,7 +4190,7 @@ public void setPropertyValues(Object object, Object[] values) {
} }
else { else {
for ( int i = 0; i < staticFetchableList.size(); i++ ) { for ( int i = 0; i < staticFetchableList.size(); i++ ) {
final AttributeMapping attribute = (AttributeMapping) staticFetchableList.get( i ); final AttributeMapping attribute = staticFetchableList.get( i ).asAttributeMapping();
final Object value = values[i]; final Object value = values[i];
if ( value != UNFETCHED_PROPERTY ) { if ( value != UNFETCHED_PROPERTY ) {
final Setter setter = attribute.getPropertyAccess().getSetter(); final Setter setter = attribute.getPropertyAccess().getSetter();
@ -4574,7 +4577,7 @@ public boolean hasNaturalIdentifier() {
@Override @Override
public void setPropertyValue(Object object, String propertyName, Object value) { public void setPropertyValue(Object object, String propertyName, Object value) {
final AttributeMapping attributeMapping = (AttributeMapping) findSubPart( propertyName, this ); final AttributeMapping attributeMapping = findSubPart( propertyName, this ).asAttributeMapping();
final AttributeMetadata attributeMetadata = attributeMapping.getAttributeMetadataAccess().resolveAttributeMetadata( this ); final AttributeMetadata attributeMetadata = attributeMapping.getAttributeMetadataAccess().resolveAttributeMetadata( this );
attributeMetadata.getPropertyAccess().getSetter().set( object, value ); attributeMetadata.getPropertyAccess().getSetter().set( object, value );
} }
@ -5690,11 +5693,11 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple sub types: ['%s', '%s']", "Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple sub types: ['%s', '%s']",
name, name,
getJavaType().getJavaType().getTypeName(), getJavaType().getJavaType().getTypeName(),
( (AttributeMapping) attribute ).getDeclaringType() attribute.asAttributeMapping().getDeclaringType()
.getJavaType() .getJavaType()
.getJavaType() .getJavaType()
.getTypeName(), .getTypeName(),
( (AttributeMapping) subDefinedAttribute ).getDeclaringType() subDefinedAttribute.asAttributeMapping().getDeclaringType()
.getJavaType() .getJavaType()
.getJavaType() .getJavaType()
.getTypeName() .getTypeName()

View File

@ -5835,8 +5835,8 @@ private Object transformDurationArithmetic(SqmBinaryArithmetic<?> expression) {
if ( type instanceof SqmExpressible) { if ( type instanceof SqmExpressible) {
adjustedTimestampType = (SqmExpressible<?>) type; adjustedTimestampType = (SqmExpressible<?>) type;
} }
else if (type instanceof AttributeMapping ) { else if (type instanceof ValueMapping ) {
adjustedTimestampType = (SqmExpressible<?>) ( (AttributeMapping) type ).getMappedType(); adjustedTimestampType = (SqmExpressible<?>) ( (ValueMapping) type ).getMappedType();
} }
else { else {
// else we know it has not been transformed // else we know it has not been transformed

View File

@ -8,6 +8,7 @@
import org.hibernate.Incubating; import org.hibernate.Incubating;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
@ -67,4 +68,8 @@ Fetch generateFetch(
default boolean incrementFetchDepth(){ default boolean incrementFetchDepth(){
return false; return false;
} }
default AttributeMapping asAttributeMapping() {
return null;
}
} }

View File

@ -51,6 +51,7 @@
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.basic.BasicResultAssembler; import org.hibernate.sql.results.graph.basic.BasicResultAssembler;
import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer; import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
import org.hibernate.sql.results.internal.NullValueAssembler; import org.hibernate.sql.results.internal.NullValueAssembler;
@ -177,7 +178,8 @@ protected AbstractEntityInitializer(
final int size = entityDescriptor.getNumberOfFetchables(); final int size = entityDescriptor.getNumberOfFetchables();
for ( int i = 0; i < size; i++ ) { for ( int i = 0; i < size; i++ ) {
final AttributeMapping attributeMapping = (AttributeMapping) entityDescriptor.getFetchable( i ); final Fetchable fetchable = entityDescriptor.getFetchable( i );
final AttributeMapping attributeMapping = fetchable.asAttributeMapping();
// todo (6.0) : somehow we need to track whether all state is loaded/resolved // todo (6.0) : somehow we need to track whether all state is loaded/resolved
// note that lazy proxies or uninitialized collections count against // note that lazy proxies or uninitialized collections count against
// that in the affirmative // that in the affirmative

View File

@ -248,7 +248,7 @@ public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourcePr
final Initializer parentInitializer = rowProcessingState.resolveInitializer( circularPath ); final Initializer parentInitializer = rowProcessingState.resolveInitializer( circularPath );
assert parentInitializer.isCollectionInitializer(); assert parentInitializer.isCollectionInitializer();
final CollectionInitializer circ = (CollectionInitializer) parentInitializer; final CollectionInitializer circ = (CollectionInitializer) parentInitializer;
final EntityPersister entityPersister = (EntityPersister) ( (AttributeMapping) fetchable ).getMappedType(); final EntityPersister entityPersister = (EntityPersister) fetchable.asAttributeMapping().getMappedType();
final CollectionKey collectionKey = circ.resolveCollectionKey( rowProcessingState ); final CollectionKey collectionKey = circ.resolveCollectionKey( rowProcessingState );
final Object key = collectionKey.getKey(); final Object key = collectionKey.getKey();
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState() final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState()