HHH-18490 Handle "concrete" generic embeddable attributes defined in mapped superclass

Also, resolve the correct expressible for function return type resolvers based on argument types.
This commit is contained in:
Marco Belladelli 2024-08-26 11:25:47 +02:00
parent 0e71253aa3
commit fc337a9294
2 changed files with 41 additions and 8 deletions

View File

@ -26,6 +26,7 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.internal.util.collections.JoinedList;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
@ -60,6 +61,8 @@ import jakarta.persistence.metamodel.IdentifiableType;
import jakarta.persistence.metamodel.SingularAttribute; import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type; import jakarta.persistence.metamodel.Type;
import static org.hibernate.internal.util.StringHelper.root;
/** /**
* Defines a context for storing information during the building of the {@link MappingMetamodelImpl}. * Defines a context for storing information during the building of the {@link MappingMetamodelImpl}.
* <p> * <p>
@ -415,9 +418,18 @@ public class MetadataContext {
final PersistentAttribute<Object, ?> attribute = final PersistentAttribute<Object, ?> attribute =
attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property ); attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property );
if ( attribute != null ) { if ( attribute != null ) {
final Property superclassProperty = getMappedSuperclassProperty(
property.getName(),
component.getMappedSuperclass()
);
if ( superclassProperty != null && superclassProperty.isGeneric() ) {
( (AttributeContainer<Object>) embeddable ).getInFlightAccess().addConcreteGenericAttribute( attribute );
}
else {
addAttribute( embeddable, attribute ); addAttribute( embeddable, attribute );
} }
} }
}
( ( AttributeContainer<?>) embeddable ).getInFlightAccess().finishUp(); ( ( AttributeContainer<?>) embeddable ).getInFlightAccess().finishUp();
// Do not process embeddables for entity types i.e. id-classes or // Do not process embeddables for entity types i.e. id-classes or
@ -643,6 +655,32 @@ public class MetadataContext {
: getMappedSuperclass( mappedSuperclass.getSuperPersistentClass() ); : getMappedSuperclass( mappedSuperclass.getSuperPersistentClass() );
} }
private Property getMappedSuperclassProperty(String propertyName, MappedSuperclass mappedSuperclass) {
if ( mappedSuperclass == null ) {
return null;
}
for ( Property property : mappedSuperclass.getDeclaredProperties() ) {
if ( property.getName().equals( propertyName ) ) {
return property;
}
}
final Property property = getMappedSuperclassProperty(
propertyName,
mappedSuperclass.getSuperMappedSuperclass()
);
if ( property != null ) {
return property;
}
if ( mappedSuperclass.getSuperPersistentClass() != null ) {
return mappedSuperclass.getSuperPersistentClass().getProperty( propertyName );
}
return null;
}
private <X> Set<SingularPersistentAttribute<? super X, ?>> buildIdClassAttributes( private <X> Set<SingularPersistentAttribute<? super X, ?>> buildIdClassAttributes(
IdentifiableDomainType<X> ownerType, IdentifiableDomainType<X> ownerType,
List<Property> properties) { List<Property> properties) {

View File

@ -241,13 +241,8 @@ public class StandardFunctionReturnTypeResolvers {
} }
private static SqmExpressible<?> getArgumentExpressible(SqmTypedNode<?> specifiedArgument) { private static SqmExpressible<?> getArgumentExpressible(SqmTypedNode<?> specifiedArgument) {
final SqmExpressible<?> expressible = specifiedArgument.getNodeType(); final SqmExpressible<?> expressible = specifiedArgument.getExpressible();
final SqmExpressible<?> specifiedArgType = expressible instanceof SqmTypedNode<?> return expressible != null ? expressible.getSqmType() : null;
? ( (SqmTypedNode<?>) expressible ).getNodeType()
: expressible;
return specifiedArgType instanceof SqmPathSource
? ( (SqmPathSource<?>) specifiedArgType ).getSqmPathType()
: specifiedArgType;
} }
public static JdbcMapping extractArgumentJdbcMapping( public static JdbcMapping extractArgumentJdbcMapping(