134
134
import org .hibernate .metamodel .mapping .ForeignKeyDescriptor ;
135
135
import org .hibernate .metamodel .mapping .JdbcMapping ;
136
136
import org .hibernate .metamodel .mapping .ManagedMappingType ;
137
- import org .hibernate .metamodel .mapping .internal .MappingModelHelper ;
138
137
import org .hibernate .metamodel .mapping .ModelPart ;
139
138
import org .hibernate .metamodel .mapping .NaturalIdMapping ;
140
139
import org .hibernate .metamodel .mapping .NonAggregatedIdentifierMapping ;
304
303
import static org .hibernate .internal .util .collections .CollectionHelper .toSmallList ;
305
304
import static org .hibernate .loader .ast .internal .MultiKeyLoadHelper .supportsSqlArrayType ;
306
305
import static org .hibernate .metamodel .RepresentationMode .POJO ;
306
+ import static org .hibernate .metamodel .mapping .internal .MappingModelHelper .isCompatibleModelPart ;
307
307
import static org .hibernate .persister .entity .DiscriminatorHelper .NOT_NULL_DISCRIMINATOR ;
308
308
import static org .hibernate .persister .entity .DiscriminatorHelper .NULL_DISCRIMINATOR ;
309
309
import static org .hibernate .pretty .MessageHelper .infoString ;
@@ -5773,50 +5773,30 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
5773
5773
}
5774
5774
}
5775
5775
5776
- if ( treatTargetType != null ) {
5777
- if ( ! treatTargetType .isTypeOrSuperType ( this ) ) {
5776
+ if ( treatTargetType == null ) {
5777
+ final var subDefinedAttribute = findSubPartInSubclassMappings ( name );
5778
+ if ( subDefinedAttribute != null ) {
5779
+ return subDefinedAttribute ;
5780
+ }
5781
+ }
5782
+ else if ( treatTargetType != this ) {
5783
+ if ( !treatTargetType .isTypeOrSuperType ( this ) ) {
5778
5784
return null ;
5779
5785
}
5780
-
5781
- if ( subclassMappingTypes != null && !subclassMappingTypes .isEmpty () ) {
5782
- for ( EntityMappingType subMappingType : subclassMappingTypes .values () ) {
5783
- if ( ! treatTargetType .isTypeOrSuperType ( subMappingType ) ) {
5784
- continue ;
5785
- }
5786
-
5787
- final ModelPart subDefinedAttribute = subMappingType .findSubTypesSubPart ( name , treatTargetType );
5788
-
5789
- if ( subDefinedAttribute != null ) {
5790
- return subDefinedAttribute ;
5791
- }
5792
- }
5786
+ // Prefer attributes defined in the treat target type or its subtypes
5787
+ final var treatTypeSubPart = treatTargetType .findSubTypesSubPart ( name , null );
5788
+ if ( treatTypeSubPart != null ) {
5789
+ return treatTypeSubPart ;
5793
5790
}
5794
- }
5795
- else {
5796
- if ( subclassMappingTypes != null && !subclassMappingTypes .isEmpty () ) {
5797
- ModelPart attribute = null ;
5798
- for ( EntityMappingType subMappingType : subclassMappingTypes .values () ) {
5799
- final ModelPart subDefinedAttribute = subMappingType .findSubTypesSubPart ( name , treatTargetType );
5800
- if ( subDefinedAttribute != null ) {
5801
- if ( attribute != null && !MappingModelHelper .isCompatibleModelPart ( attribute , subDefinedAttribute ) ) {
5802
- throw new PathException (
5803
- String .format (
5804
- Locale .ROOT ,
5805
- "Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'" ,
5806
- name ,
5807
- getJavaType ().getTypeName (),
5808
- attribute .asAttributeMapping ().getDeclaringType ()
5809
- .getJavaType ().getTypeName (),
5810
- subDefinedAttribute .asAttributeMapping ().getDeclaringType ()
5811
- .getJavaType ().getTypeName ()
5812
- )
5813
- );
5814
- }
5815
- attribute = subDefinedAttribute ;
5791
+ else {
5792
+ // If not found, look in the treat target type's supertypes
5793
+ EntityMappingType superType = treatTargetType .getSuperMappingType ();
5794
+ while ( superType != this ) {
5795
+ final var superTypeSubPart = superType .findDeclaredAttributeMapping ( name );
5796
+ if ( superTypeSubPart != null ) {
5797
+ return superTypeSubPart ;
5816
5798
}
5817
- }
5818
- if ( attribute != null ) {
5819
- return attribute ;
5799
+ superType = superType .getSuperMappingType ();
5820
5800
}
5821
5801
}
5822
5802
}
@@ -5838,22 +5818,37 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
5838
5818
}
5839
5819
}
5840
5820
5821
+ private ModelPart findSubPartInSubclassMappings (String name ) {
5822
+ ModelPart attribute = null ;
5823
+ if ( isNotEmpty ( subclassMappingTypes ) ) {
5824
+ for ( var subMappingType : subclassMappingTypes .values () ) {
5825
+ final var subDefinedAttribute = subMappingType .findSubTypesSubPart ( name , null );
5826
+ if ( subDefinedAttribute != null ) {
5827
+ if ( attribute != null && !isCompatibleModelPart ( attribute , subDefinedAttribute ) ) {
5828
+ throw new PathException ( String .format (
5829
+ Locale .ROOT ,
5830
+ "Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'" ,
5831
+ name ,
5832
+ getJavaType ().getTypeName (),
5833
+ attribute .asAttributeMapping ().getDeclaringType ().getJavaType ().getTypeName (),
5834
+ subDefinedAttribute .asAttributeMapping ().getDeclaringType ().getJavaType ().getTypeName ()
5835
+ ) );
5836
+ }
5837
+ attribute = subDefinedAttribute ;
5838
+ }
5839
+ }
5840
+ }
5841
+ return attribute ;
5842
+ }
5843
+
5841
5844
@ Override
5842
5845
public ModelPart findSubTypesSubPart (String name , EntityMappingType treatTargetType ) {
5843
5846
final AttributeMapping declaredAttribute = declaredAttributeMappings .get ( name );
5844
5847
if ( declaredAttribute != null ) {
5845
5848
return declaredAttribute ;
5846
5849
}
5847
5850
else {
5848
- if ( subclassMappingTypes != null && !subclassMappingTypes .isEmpty () ) {
5849
- for ( EntityMappingType subMappingType : subclassMappingTypes .values () ) {
5850
- final ModelPart subDefinedAttribute = subMappingType .findSubTypesSubPart ( name , treatTargetType );
5851
- if ( subDefinedAttribute != null ) {
5852
- return subDefinedAttribute ;
5853
- }
5854
- }
5855
- }
5856
- return null ;
5851
+ return findSubPartInSubclassMappings ( name );
5857
5852
}
5858
5853
}
5859
5854
0 commit comments