Skip to content

Commit 16a4d07

Browse files
committed
HHH-19756 Improve sub-part resolution when specifying a treat type
1 parent ff2e468 commit 16a4d07

File tree

1 file changed

+45
-49
lines changed

1 file changed

+45
-49
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@
333333
import static org.hibernate.internal.util.collections.CollectionHelper.toSmallList;
334334
import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.supportsSqlArrayType;
335335
import static org.hibernate.metamodel.RepresentationMode.POJO;
336+
import static org.hibernate.metamodel.mapping.MappingModelHelper.isCompatibleModelPart;
336337
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
337338
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
338339
import static org.hibernate.pretty.MessageHelper.infoString;
@@ -6219,50 +6220,30 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
62196220
}
62206221
}
62216222

6222-
if ( treatTargetType != null ) {
6223-
if ( ! treatTargetType.isTypeOrSuperType( this ) ) {
6223+
if ( treatTargetType == null ) {
6224+
final var subDefinedAttribute = findSubPartInSubclassMappings( name );
6225+
if ( subDefinedAttribute != null ) {
6226+
return subDefinedAttribute;
6227+
}
6228+
}
6229+
else if ( treatTargetType != this ) {
6230+
if ( !treatTargetType.isTypeOrSuperType( this ) ) {
62246231
return null;
62256232
}
6226-
6227-
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
6228-
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
6229-
if ( ! treatTargetType.isTypeOrSuperType( subMappingType ) ) {
6230-
continue;
6231-
}
6232-
6233-
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
6234-
6235-
if ( subDefinedAttribute != null ) {
6236-
return subDefinedAttribute;
6237-
}
6238-
}
6233+
// Prefer attributes defined in the treat target type or its subtypes
6234+
final var treatTypeSubPart = treatTargetType.findSubTypesSubPart( name, null );
6235+
if ( treatTypeSubPart != null ) {
6236+
return treatTypeSubPart;
62396237
}
6240-
}
6241-
else {
6242-
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
6243-
ModelPart attribute = null;
6244-
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
6245-
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
6246-
if ( subDefinedAttribute != null ) {
6247-
if ( attribute != null && !MappingModelHelper.isCompatibleModelPart( attribute, subDefinedAttribute ) ) {
6248-
throw new PathException(
6249-
String.format(
6250-
Locale.ROOT,
6251-
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'",
6252-
name,
6253-
getJavaType().getTypeName(),
6254-
attribute.asAttributeMapping().getDeclaringType()
6255-
.getJavaType().getTypeName(),
6256-
subDefinedAttribute.asAttributeMapping().getDeclaringType()
6257-
.getJavaType().getTypeName()
6258-
)
6259-
);
6260-
}
6261-
attribute = subDefinedAttribute;
6238+
else {
6239+
// If not found, look in the treat target type's supertypes
6240+
EntityMappingType superType = treatTargetType.getSuperMappingType();
6241+
while ( superType != this ) {
6242+
final var superTypeSubPart = superType.findDeclaredAttributeMapping( name );
6243+
if ( superTypeSubPart != null ) {
6244+
return superTypeSubPart;
62626245
}
6263-
}
6264-
if ( attribute != null ) {
6265-
return attribute;
6246+
superType = superType.getSuperMappingType();
62666247
}
62676248
}
62686249
}
@@ -6285,22 +6266,37 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
62856266
}
62866267
}
62876268

6269+
private ModelPart findSubPartInSubclassMappings(String name) {
6270+
ModelPart attribute = null;
6271+
if ( isNotEmpty( subclassMappingTypes ) ) {
6272+
for ( var subMappingType : subclassMappingTypes.values() ) {
6273+
final var subDefinedAttribute = subMappingType.findSubTypesSubPart( name, null );
6274+
if ( subDefinedAttribute != null ) {
6275+
if ( attribute != null && !isCompatibleModelPart( attribute, subDefinedAttribute ) ) {
6276+
throw new PathException( String.format(
6277+
Locale.ROOT,
6278+
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'",
6279+
name,
6280+
getJavaType().getTypeName(),
6281+
attribute.asAttributeMapping().getDeclaringType().getJavaType().getTypeName(),
6282+
subDefinedAttribute.asAttributeMapping().getDeclaringType().getJavaType().getTypeName()
6283+
) );
6284+
}
6285+
attribute = subDefinedAttribute;
6286+
}
6287+
}
6288+
}
6289+
return attribute;
6290+
}
6291+
62886292
@Override
62896293
public ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetType) {
62906294
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
62916295
if ( declaredAttribute != null ) {
62926296
return declaredAttribute;
62936297
}
62946298
else {
6295-
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
6296-
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
6297-
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
6298-
if ( subDefinedAttribute != null ) {
6299-
return subDefinedAttribute;
6300-
}
6301-
}
6302-
}
6303-
return null;
6299+
return findSubPartInSubclassMappings( name );
63046300
}
63056301
}
63066302

0 commit comments

Comments
 (0)