HHH-18103 Correct metamodel for embeddables with a mapped superclass
This commit is contained in:
parent
00c7707de0
commit
062afdb6cd
|
@ -287,7 +287,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
}
|
}
|
||||||
if ( inheritanceState.isEmbeddableSuperclass() ) {
|
if ( inheritanceState.isEmbeddableSuperclass() ) {
|
||||||
persistentClass.addMappedSuperclassProperty( property );
|
persistentClass.addMappedSuperclassProperty( property );
|
||||||
addPropertyToMappedSuperclass( property, declaringClass );
|
addPropertyToMappedSuperclass( property, declaringClass, getContext() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
persistentClass.addProperty( property );
|
persistentClass.addProperty( property );
|
||||||
|
@ -298,10 +298,10 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
|
static void addPropertyToMappedSuperclass(Property prop, XClass declaringClass, MetadataBuildingContext context) {
|
||||||
final Class<?> type = getContext().getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
final Class<?> type = context.getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
||||||
final MappedSuperclass superclass = getContext().getMetadataCollector().getMappedSuperclass( type );
|
final MappedSuperclass superclass = context.getMetadataCollector().getMappedSuperclass( type );
|
||||||
prepareActualProperty( prop, type, true, getContext(), superclass::addDeclaredProperty );
|
prepareActualProperty( prop, type, true, context, superclass::addDeclaredProperty );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepareActualProperty(
|
static void prepareActualProperty(
|
||||||
|
@ -458,7 +458,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
}
|
}
|
||||||
if ( inheritanceState.isEmbeddableSuperclass() ) {
|
if ( inheritanceState.isEmbeddableSuperclass() ) {
|
||||||
join.addMappedSuperclassProperty( property );
|
join.addMappedSuperclassProperty( property );
|
||||||
addPropertyToMappedSuperclass( property, declaringClass );
|
addPropertyToMappedSuperclass( property, declaringClass, getContext() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
join.addProperty( property );
|
join.addProperty( property );
|
||||||
|
|
|
@ -30,7 +30,10 @@ import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.JoinColumn;
|
import jakarta.persistence.JoinColumn;
|
||||||
import jakarta.persistence.JoinTable;
|
import jakarta.persistence.JoinTable;
|
||||||
|
|
||||||
|
import static org.hibernate.boot.model.internal.ClassPropertyHolder.addPropertyToMappedSuperclass;
|
||||||
|
import static org.hibernate.boot.model.internal.ClassPropertyHolder.handleGenericComponentProperty;
|
||||||
import static org.hibernate.boot.model.internal.HCANNHelper.hasAnnotation;
|
import static org.hibernate.boot.model.internal.HCANNHelper.hasAnnotation;
|
||||||
|
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
|
||||||
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
||||||
import static org.hibernate.internal.util.StringHelper.qualifyConditionally;
|
import static org.hibernate.internal.util.StringHelper.qualifyConditionally;
|
||||||
import static org.hibernate.spi.NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
|
import static org.hibernate.spi.NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
|
||||||
|
@ -67,6 +70,7 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
|
||||||
private final Component component;
|
private final Component component;
|
||||||
private final boolean isOrWithinEmbeddedId;
|
private final boolean isOrWithinEmbeddedId;
|
||||||
private final boolean isWithinElementCollection;
|
private final boolean isWithinElementCollection;
|
||||||
|
private final Map<XClass, InheritanceState> inheritanceStatePerClass;
|
||||||
|
|
||||||
private final String embeddedAttributeName;
|
private final String embeddedAttributeName;
|
||||||
private final Map<String,AttributeConversionInfo> attributeConversionInfoMap;
|
private final Map<String,AttributeConversionInfo> attributeConversionInfoMap;
|
||||||
|
@ -76,7 +80,8 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
|
||||||
String path,
|
String path,
|
||||||
PropertyData inferredData,
|
PropertyData inferredData,
|
||||||
PropertyHolder parent,
|
PropertyHolder parent,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context,
|
||||||
|
Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||||
super( path, parent, inferredData.getPropertyClass(), context );
|
super( path, parent, inferredData.getPropertyClass(), context );
|
||||||
final XProperty embeddedXProperty = inferredData.getProperty();
|
final XProperty embeddedXProperty = inferredData.getProperty();
|
||||||
setCurrentProperty( embeddedXProperty );
|
setCurrentProperty( embeddedXProperty );
|
||||||
|
@ -85,6 +90,7 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
|
||||||
|| hasAnnotation( embeddedXProperty, Id.class, EmbeddedId.class );
|
|| hasAnnotation( embeddedXProperty, Id.class, EmbeddedId.class );
|
||||||
this.isWithinElementCollection = parent.isWithinElementCollection() ||
|
this.isWithinElementCollection = parent.isWithinElementCollection() ||
|
||||||
parent instanceof CollectionPropertyHolder;
|
parent instanceof CollectionPropertyHolder;
|
||||||
|
this.inheritanceStatePerClass = inheritanceStatePerClass;
|
||||||
|
|
||||||
if ( embeddedXProperty != null ) {
|
if ( embeddedXProperty != null ) {
|
||||||
this.embeddedAttributeName = embeddedXProperty.getName();
|
this.embeddedAttributeName = embeddedXProperty.getName();
|
||||||
|
@ -314,6 +320,13 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addProperty(Property prop, XClass declaringClass) {
|
public void addProperty(Property prop, XClass declaringClass) {
|
||||||
|
handleGenericComponentProperty( prop, getContext() );
|
||||||
|
if ( declaringClass != null ) {
|
||||||
|
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
|
||||||
|
if ( inheritanceState != null && inheritanceState.isEmbeddableSuperclass() ) {
|
||||||
|
addPropertyToMappedSuperclass( prop, declaringClass, getContext() );
|
||||||
|
}
|
||||||
|
}
|
||||||
component.addProperty( prop, declaringClass );
|
component.addProperty( prop, declaringClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,7 +353,8 @@ public class EmbeddableBinder {
|
||||||
subpath,
|
subpath,
|
||||||
inferredData,
|
inferredData,
|
||||||
propertyHolder,
|
propertyHolder,
|
||||||
context
|
context,
|
||||||
|
inheritanceStatePerClass
|
||||||
);
|
);
|
||||||
|
|
||||||
// propertyHolder here is the owner of the component property.
|
// propertyHolder here is the owner of the component property.
|
||||||
|
@ -381,18 +382,23 @@ public class EmbeddableBinder {
|
||||||
context
|
context
|
||||||
);
|
);
|
||||||
|
|
||||||
bindDiscriminator(
|
final InheritanceState inheritanceState = inheritanceStatePerClass.get( returnedClassOrElement );
|
||||||
component,
|
if ( inheritanceState != null ) {
|
||||||
returnedClassOrElement,
|
inheritanceState.postProcess( component );
|
||||||
propertyHolder,
|
// Main entry point for binding embeddable inheritance
|
||||||
subholder,
|
bindDiscriminator(
|
||||||
inferredData,
|
component,
|
||||||
inheritanceStatePerClass,
|
returnedClassOrElement,
|
||||||
context
|
propertyHolder,
|
||||||
);
|
subholder,
|
||||||
|
inferredData,
|
||||||
|
inheritanceState,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, String> subclassToSuperclass = component.isPolymorphic() ? new HashMap<>() : null;
|
|
||||||
final XClass annotatedClass = inferredData.getPropertyClass();
|
final XClass annotatedClass = inferredData.getPropertyClass();
|
||||||
|
final Map<String, String> subclassToSuperclass = component.isPolymorphic() ? new HashMap<>() : null;
|
||||||
final List<PropertyData> classElements = collectClassElements(
|
final List<PropertyData> classElements = collectClassElements(
|
||||||
propertyAccessor,
|
propertyAccessor,
|
||||||
context,
|
context,
|
||||||
|
@ -487,13 +493,11 @@ public class EmbeddableBinder {
|
||||||
PropertyHolder parentHolder,
|
PropertyHolder parentHolder,
|
||||||
PropertyHolder holder,
|
PropertyHolder holder,
|
||||||
PropertyData propertyData,
|
PropertyData propertyData,
|
||||||
Map<XClass, InheritanceState> inheritanceStatePerClass,
|
InheritanceState inheritanceState,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context) {
|
||||||
final InheritanceState inheritanceState = inheritanceStatePerClass.get( componentClass );
|
|
||||||
if ( inheritanceState == null ) {
|
if ( inheritanceState == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AnnotatedDiscriminatorColumn discriminatorColumn = processEmbeddableDiscriminatorProperties(
|
final AnnotatedDiscriminatorColumn discriminatorColumn = processEmbeddableDiscriminatorProperties(
|
||||||
componentClass,
|
componentClass,
|
||||||
propertyData,
|
propertyData,
|
||||||
|
|
|
@ -17,7 +17,9 @@ import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
import org.hibernate.boot.spi.AccessType;
|
import org.hibernate.boot.spi.AccessType;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.boot.spi.PropertyData;
|
import org.hibernate.boot.spi.PropertyData;
|
||||||
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
|
|
||||||
import jakarta.persistence.Access;
|
import jakarta.persistence.Access;
|
||||||
import jakarta.persistence.EmbeddedId;
|
import jakarta.persistence.EmbeddedId;
|
||||||
|
@ -163,6 +165,15 @@ public class InheritanceState {
|
||||||
return elementsToProcess;
|
return elementsToProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void postProcess(Component component) {
|
||||||
|
if ( classesToProcessForMappedSuperclass.isEmpty() ) {
|
||||||
|
// Component classes might be processed more than once,
|
||||||
|
// so only do this the first time we encounter them
|
||||||
|
getMappedSuperclassesTillNextEntityOrdered();
|
||||||
|
}
|
||||||
|
addMappedSuperClassInMetadata( component );
|
||||||
|
}
|
||||||
|
|
||||||
public XClass getClassWithIdClass(boolean evenIfSubclass) {
|
public XClass getClassWithIdClass(boolean evenIfSubclass) {
|
||||||
if ( !evenIfSubclass && hasParents() ) {
|
if ( !evenIfSubclass && hasParents() ) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -300,7 +311,21 @@ public class InheritanceState {
|
||||||
while ( superclassState != null && superclassState.isEmbeddableSuperclass() );
|
while ( superclassState != null && superclassState.isEmbeddableSuperclass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addMappedSuperClassInMetadata(Component component) {
|
||||||
|
org.hibernate.mapping.MappedSuperclass mappedSuperclass = processMappedSuperclass( component.getTable() );
|
||||||
|
if ( mappedSuperclass != null ) {
|
||||||
|
component.setMappedSuperclass( mappedSuperclass );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addMappedSuperClassInMetadata(PersistentClass persistentClass) {
|
private void addMappedSuperClassInMetadata(PersistentClass persistentClass) {
|
||||||
|
org.hibernate.mapping.MappedSuperclass mappedSuperclass = processMappedSuperclass( persistentClass.getImplicitTable() );
|
||||||
|
if ( mappedSuperclass != null ) {
|
||||||
|
persistentClass.setSuperMappedSuperclass( mappedSuperclass );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private org.hibernate.mapping.MappedSuperclass processMappedSuperclass(Table implicitTable) {
|
||||||
//add @MappedSuperclass in the metadata
|
//add @MappedSuperclass in the metadata
|
||||||
// classes from 0 to n-1 are @MappedSuperclass and should be linked
|
// classes from 0 to n-1 are @MappedSuperclass and should be linked
|
||||||
final InheritanceState superEntityState = getInheritanceStateOfSuperEntity( clazz, inheritanceStatePerClass );
|
final InheritanceState superEntityState = getInheritanceStateOfSuperEntity( clazz, inheritanceStatePerClass );
|
||||||
|
@ -317,14 +342,12 @@ public class InheritanceState {
|
||||||
//add MappedSuperclass if not already there
|
//add MappedSuperclass if not already there
|
||||||
mappedSuperclass = buildingContext.getMetadataCollector().getMappedSuperclass( type );
|
mappedSuperclass = buildingContext.getMetadataCollector().getMappedSuperclass( type );
|
||||||
if ( mappedSuperclass == null ) {
|
if ( mappedSuperclass == null ) {
|
||||||
mappedSuperclass = new org.hibernate.mapping.MappedSuperclass( parentSuperclass, superEntity, persistentClass.getImplicitTable() );
|
mappedSuperclass = new org.hibernate.mapping.MappedSuperclass( parentSuperclass, superEntity, implicitTable );
|
||||||
mappedSuperclass.setMappedClass( type );
|
mappedSuperclass.setMappedClass( type );
|
||||||
buildingContext.getMetadataCollector().addMappedSuperclass( type, mappedSuperclass );
|
buildingContext.getMetadataCollector().addMappedSuperclass( type, mappedSuperclass );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( mappedSuperclass != null ) {
|
return mappedSuperclass;
|
||||||
persistentClass.setSuperMappedSuperclass( mappedSuperclass );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ElementsToProcess {
|
public static final class ElementsToProcess {
|
||||||
|
|
|
@ -54,8 +54,9 @@ public final class PropertyHolderBuilder {
|
||||||
String path,
|
String path,
|
||||||
PropertyData inferredData,
|
PropertyData inferredData,
|
||||||
PropertyHolder parent,
|
PropertyHolder parent,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context,
|
||||||
return new ComponentPropertyHolder( component, path, inferredData, parent, context );
|
Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||||
|
return new ComponentPropertyHolder( component, path, inferredData, parent, context, inheritanceStatePerClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -86,6 +86,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
private boolean isKey;
|
private boolean isKey;
|
||||||
private Boolean isGeneric;
|
private Boolean isGeneric;
|
||||||
private String roleName;
|
private String roleName;
|
||||||
|
private MappedSuperclass mappedSuperclass;
|
||||||
private Value discriminator;
|
private Value discriminator;
|
||||||
private transient DiscriminatorType<?> discriminatorType;
|
private transient DiscriminatorType<?> discriminatorType;
|
||||||
private Map<Object, String> discriminatorValues;
|
private Map<Object, String> discriminatorValues;
|
||||||
|
@ -601,6 +602,14 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
this.roleName = roleName;
|
this.roleName = roleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MappedSuperclass getMappedSuperclass() {
|
||||||
|
return mappedSuperclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMappedSuperclass(MappedSuperclass mappedSuperclass) {
|
||||||
|
this.mappedSuperclass = mappedSuperclass;
|
||||||
|
}
|
||||||
|
|
||||||
public Value getDiscriminator() {
|
public Value getDiscriminator() {
|
||||||
return discriminator;
|
return discriminator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.List;
|
import org.hibernate.mapping.List;
|
||||||
import org.hibernate.mapping.Map;
|
import org.hibernate.mapping.Map;
|
||||||
|
import org.hibernate.mapping.MappedSuperclass;
|
||||||
import org.hibernate.mapping.OneToMany;
|
import org.hibernate.mapping.OneToMany;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
@ -44,6 +45,7 @@ import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||||
|
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||||
|
@ -263,10 +265,20 @@ public class AttributeFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final MappedSuperclass mappedSuperclass = component.getMappedSuperclass();
|
||||||
|
final MappedSuperclassDomainType<? super Y> superType;
|
||||||
|
if ( mappedSuperclass != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
superType = (MappedSuperclassDomainType<? super Y>) context.locateMappedSuperclassType( mappedSuperclass );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
superType = null;
|
||||||
|
}
|
||||||
|
|
||||||
final DomainType<?> discriminatorType = component.isPolymorphic() ? component.getDiscriminatorType() : null;
|
final DomainType<?> discriminatorType = component.isPolymorphic() ? component.getDiscriminatorType() : null;
|
||||||
final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<>(
|
final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<>(
|
||||||
context.getJavaTypeRegistry().resolveManagedTypeDescriptor( embeddableClass ),
|
context.getJavaTypeRegistry().resolveManagedTypeDescriptor( embeddableClass ),
|
||||||
null,
|
superType,
|
||||||
discriminatorType,
|
discriminatorType,
|
||||||
false,
|
false,
|
||||||
context.getJpaMetamodel()
|
context.getJpaMetamodel()
|
||||||
|
@ -409,7 +421,7 @@ public class AttributeFactory {
|
||||||
else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS ) {
|
else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS ) {
|
||||||
final PersistentClass persistentClass =
|
final PersistentClass persistentClass =
|
||||||
metadataContext.getPersistentClassHostingProperties( (MappedSuperclassTypeImpl<?>) ownerType );
|
metadataContext.getPersistentClassHostingProperties( (MappedSuperclassTypeImpl<?>) ownerType );
|
||||||
return metadataContext.getMetamodel().findEntityDescriptor( persistentClass.getClassName() );
|
return persistentClass != null ? metadataContext.getMetamodel().findEntityDescriptor( persistentClass.getClassName() ) : null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new AssertionFailure( "Cannot get the metamodel for PersistenceType: " + persistenceType );
|
throw new AssertionFailure( "Cannot get the metamodel for PersistenceType: " + persistenceType );
|
||||||
|
@ -646,6 +658,13 @@ public class AttributeFactory {
|
||||||
private static final MemberResolver embeddedMemberResolver = (attributeContext, metadataContext) -> {
|
private static final MemberResolver embeddedMemberResolver = (attributeContext, metadataContext) -> {
|
||||||
// the owner is an embeddable
|
// the owner is an embeddable
|
||||||
final EmbeddableDomainType<?> ownerType = (EmbeddableDomainType<?>) attributeContext.getOwnerType();
|
final EmbeddableDomainType<?> ownerType = (EmbeddableDomainType<?>) attributeContext.getOwnerType();
|
||||||
|
return resolveEmbeddedMember( attributeContext.getPropertyMapping(), ownerType, metadataContext );
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Member resolveEmbeddedMember(
|
||||||
|
Property property,
|
||||||
|
EmbeddableDomainType<?> ownerType,
|
||||||
|
MetadataContext metadataContext) {
|
||||||
final Component ownerBootDescriptor = metadataContext.getEmbeddableBootDescriptor( ownerType );
|
final Component ownerBootDescriptor = metadataContext.getEmbeddableBootDescriptor( ownerType );
|
||||||
|
|
||||||
final CompositeTypeImplementor ownerComponentType = (CompositeTypeImplementor) ownerBootDescriptor.getType();
|
final CompositeTypeImplementor ownerComponentType = (CompositeTypeImplementor) ownerBootDescriptor.getType();
|
||||||
|
@ -655,16 +674,15 @@ public class AttributeFactory {
|
||||||
ownerRepresentationStrategy( metadataContext, ownerMappingModelDescriptor, ownerBootDescriptor );
|
ownerRepresentationStrategy( metadataContext, ownerMappingModelDescriptor, ownerBootDescriptor );
|
||||||
|
|
||||||
if ( ownerRepStrategy.getMode() == RepresentationMode.MAP ) {
|
if ( ownerRepStrategy.getMode() == RepresentationMode.MAP ) {
|
||||||
final Property propertyMapping = attributeContext.getPropertyMapping();
|
return new MapMember( property.getName(), property.getType().getReturnedClass() );
|
||||||
return new MapMember( propertyMapping.getName(), propertyMapping.getType().getReturnedClass() );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return ownerRepStrategy
|
return ownerRepStrategy
|
||||||
.resolvePropertyAccess( attributeContext.getPropertyMapping() )
|
.resolvePropertyAccess( property )
|
||||||
.getGetter()
|
.getGetter()
|
||||||
.getMember();
|
.getMember();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
private static EmbeddableRepresentationStrategy ownerRepresentationStrategy(
|
private static EmbeddableRepresentationStrategy ownerRepresentationStrategy(
|
||||||
MetadataContext metadataContext, EmbeddableValuedModelPart ownerMappingModelDescriptor, Component ownerBootDescriptor) {
|
MetadataContext metadataContext, EmbeddableValuedModelPart ownerMappingModelDescriptor, Component ownerBootDescriptor) {
|
||||||
|
@ -688,7 +706,11 @@ public class AttributeFactory {
|
||||||
|
|
||||||
private static final MemberResolver virtualIdentifierMemberResolver = (attributeContext, metadataContext) -> {
|
private static final MemberResolver virtualIdentifierMemberResolver = (attributeContext, metadataContext) -> {
|
||||||
final AbstractIdentifiableType<?> identifiableType = (AbstractIdentifiableType<?>) attributeContext.getOwnerType();
|
final AbstractIdentifiableType<?> identifiableType = (AbstractIdentifiableType<?>) attributeContext.getOwnerType();
|
||||||
final EntityPersister entityPersister = getDeclarerEntityPersister( identifiableType, metadataContext );
|
final EntityPersister declaringEntity = getDeclaringEntity( identifiableType, metadataContext );
|
||||||
|
return resolveVirtualIdentifierMember( attributeContext.getPropertyMapping(), declaringEntity );
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Member resolveVirtualIdentifierMember( Property property, EntityPersister entityPersister) {
|
||||||
final EntityIdentifierMapping identifierMapping = entityPersister.getIdentifierMapping();
|
final EntityIdentifierMapping identifierMapping = entityPersister.getIdentifierMapping();
|
||||||
|
|
||||||
if ( identifierMapping.getNature() != EntityIdentifierMapping.Nature.VIRTUAL ) {
|
if ( identifierMapping.getNature() != EntityIdentifierMapping.Nature.VIRTUAL ) {
|
||||||
|
@ -697,7 +719,7 @@ public class AttributeFactory {
|
||||||
|
|
||||||
final CompositeIdentifierMapping cid = (CompositeIdentifierMapping) identifierMapping;
|
final CompositeIdentifierMapping cid = (CompositeIdentifierMapping) identifierMapping;
|
||||||
final EmbeddableMappingType embeddable = cid.getPartMappingType();
|
final EmbeddableMappingType embeddable = cid.getPartMappingType();
|
||||||
final String attributeName = attributeContext.getPropertyMapping().getName();
|
final String attributeName = property.getName();
|
||||||
final AttributeMapping attributeMapping = embeddable.findAttributeMapping( attributeName );
|
final AttributeMapping attributeMapping = embeddable.findAttributeMapping( attributeName );
|
||||||
if ( attributeMapping == null ) {
|
if ( attributeMapping == null ) {
|
||||||
throw new PropertyNotFoundException(
|
throw new PropertyNotFoundException(
|
||||||
|
@ -708,9 +730,9 @@ public class AttributeFactory {
|
||||||
|
|
||||||
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
||||||
return getter instanceof PropertyAccessMapImpl.GetterImpl
|
return getter instanceof PropertyAccessMapImpl.GetterImpl
|
||||||
? new MapMember( attributeName, attributeContext.getPropertyMapping().getType().getReturnedClass() )
|
? new MapMember( attributeName, property.getType().getReturnedClass() )
|
||||||
: getter.getMember();
|
: getter.getMember();
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Member} resolver for normal attributes.
|
* A {@link Member} resolver for normal attributes.
|
||||||
|
@ -722,29 +744,66 @@ public class AttributeFactory {
|
||||||
if ( Type.PersistenceType.EMBEDDABLE == persistenceType ) {
|
if ( Type.PersistenceType.EMBEDDABLE == persistenceType ) {
|
||||||
return embeddedMemberResolver.resolveMember( attributeContext, metadataContext );
|
return embeddedMemberResolver.resolveMember( attributeContext, metadataContext );
|
||||||
}
|
}
|
||||||
else if ( Type.PersistenceType.ENTITY == persistenceType
|
else if ( Type.PersistenceType.MAPPED_SUPERCLASS == persistenceType ) {
|
||||||
|| Type.PersistenceType.MAPPED_SUPERCLASS == persistenceType ) {
|
return resolveMappedSuperclassMember(
|
||||||
final AbstractIdentifiableType<?> identifiableType = (AbstractIdentifiableType<?>) ownerType;
|
property,
|
||||||
final EntityPersister declaringEntityPersister = getDeclaringEntity( identifiableType, metadataContext );
|
(MappedSuperclassDomainType<?>) ownerType,
|
||||||
final String propertyName = property.getName();
|
metadataContext
|
||||||
|
);
|
||||||
final AttributeMapping attributeMapping = declaringEntityPersister.findAttributeMapping( propertyName );
|
}
|
||||||
if ( attributeMapping == null ) {
|
else if ( Type.PersistenceType.ENTITY == persistenceType ) {
|
||||||
// just like in #determineIdentifierJavaMember , this *should* indicate we have an IdClass mapping
|
return resolveEntityMember( property, getDeclaringEntity( (AbstractIdentifiableType<?>) ownerType, metadataContext ) );
|
||||||
return virtualIdentifierMemberResolver.resolveMember( attributeContext, metadataContext );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final Getter getter = getter( declaringEntityPersister, property );
|
|
||||||
return getter instanceof PropertyAccessMapImpl.GetterImpl
|
|
||||||
? new MapMember( propertyName, property.getType().getReturnedClass() )
|
|
||||||
: getter.getMember();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException( "Unexpected owner type : " + persistenceType );
|
throw new IllegalArgumentException( "Unexpected owner type : " + persistenceType );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static Member resolveEntityMember(Property property, EntityPersister declaringEntity) {
|
||||||
|
final String propertyName = property.getName();
|
||||||
|
final AttributeMapping attributeMapping = declaringEntity.findAttributeMapping( propertyName );
|
||||||
|
if ( attributeMapping == null ) {
|
||||||
|
// just like in #determineIdentifierJavaMember , this *should* indicate we have an IdClass mapping
|
||||||
|
return resolveVirtualIdentifierMember( property, declaringEntity );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Getter getter = getter( declaringEntity, property );
|
||||||
|
return getter instanceof PropertyAccessMapImpl.GetterImpl
|
||||||
|
? new MapMember( propertyName, property.getType().getReturnedClass() )
|
||||||
|
: getter.getMember();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Member resolveMappedSuperclassMember(
|
||||||
|
Property property,
|
||||||
|
MappedSuperclassDomainType<?> ownerType,
|
||||||
|
MetadataContext metadataContext) {
|
||||||
|
final EntityPersister declaringEntity = getDeclaringEntity( (AbstractIdentifiableType<?>) ownerType, metadataContext );
|
||||||
|
if ( declaringEntity != null ) {
|
||||||
|
return resolveEntityMember( property, declaringEntity );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final ManagedDomainType<?> subType = ownerType.getSubTypes().iterator().next();
|
||||||
|
final Type.PersistenceType persistenceType = subType.getPersistenceType();
|
||||||
|
if ( persistenceType == Type.PersistenceType.ENTITY ) {
|
||||||
|
return resolveEntityMember( property, getDeclaringEntity( (AbstractIdentifiableType<?>) subType, metadataContext ) );
|
||||||
|
}
|
||||||
|
else if ( persistenceType == Type.PersistenceType.EMBEDDABLE ) {
|
||||||
|
return resolveEmbeddedMember( property, (EmbeddableDomainType<?>) subType, metadataContext );
|
||||||
|
}
|
||||||
|
else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS ) {
|
||||||
|
return resolveMappedSuperclassMember(
|
||||||
|
property,
|
||||||
|
(MappedSuperclassDomainType<?>) subType,
|
||||||
|
metadataContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException( "Unexpected sub-type: " + persistenceType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final MemberResolver identifierMemberResolver = (attributeContext, metadataContext) -> {
|
private final MemberResolver identifierMemberResolver = (attributeContext, metadataContext) -> {
|
||||||
final AbstractIdentifiableType<?> identifiableType =
|
final AbstractIdentifiableType<?> identifiableType =
|
||||||
(AbstractIdentifiableType<?>) attributeContext.getOwnerType();
|
(AbstractIdentifiableType<?>) attributeContext.getOwnerType();
|
||||||
|
|
|
@ -211,7 +211,9 @@ public class MetadataContext {
|
||||||
identifiableTypesByName.put( mappedSuperclassType.getTypeName(), mappedSuperclassType );
|
identifiableTypesByName.put( mappedSuperclassType.getTypeName(), mappedSuperclassType );
|
||||||
mappedSuperclassByMappedSuperclassMapping.put( mappedSuperclass, mappedSuperclassType );
|
mappedSuperclassByMappedSuperclassMapping.put( mappedSuperclass, mappedSuperclassType );
|
||||||
orderedMappings.add( mappedSuperclass );
|
orderedMappings.add( mappedSuperclass );
|
||||||
mappedSuperClassTypeToPersistentClass.put( mappedSuperclassType, getEntityWorkedOn() );
|
if ( !stackOfPersistentClassesBeingProcessed.isEmpty() ) {
|
||||||
|
mappedSuperClassTypeToPersistentClass.put( mappedSuperclassType, getEntityWorkedOn() );
|
||||||
|
}
|
||||||
|
|
||||||
knownMappedSuperclasses.remove( mappedSuperclass );
|
knownMappedSuperclasses.remove( mappedSuperclass );
|
||||||
}
|
}
|
||||||
|
@ -804,14 +806,7 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PersistentClass getPersistentClassHostingProperties(MappedSuperclassTypeImpl<?> mappedSuperclassType) {
|
public PersistentClass getPersistentClassHostingProperties(MappedSuperclassTypeImpl<?> mappedSuperclassType) {
|
||||||
final PersistentClass persistentClass = mappedSuperClassTypeToPersistentClass.get( mappedSuperclassType );
|
return mappedSuperClassTypeToPersistentClass.get( mappedSuperclassType );
|
||||||
if ( persistentClass == null ) {
|
|
||||||
throw new AssertionFailure(
|
|
||||||
"Could not find PersistentClass for MappedSuperclassType: "
|
|
||||||
+ mappedSuperclassType.getJavaType()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return persistentClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<MappedSuperclass> getUnusedMappedSuperclasses() {
|
public Set<MappedSuperclass> getUnusedMappedSuperclasses() {
|
||||||
|
|
|
@ -32,7 +32,8 @@ public class AuditedEmbeddableWithNoDeclaredDataTest extends BaseEnversJPAFuncti
|
||||||
return new Class[] {
|
return new Class[] {
|
||||||
EntityWithAuditedEmbeddableWithNoDeclaredData.class,
|
EntityWithAuditedEmbeddableWithNoDeclaredData.class,
|
||||||
AbstractAuditedEmbeddable.class,
|
AbstractAuditedEmbeddable.class,
|
||||||
AuditedEmbeddableWithDeclaredData.class
|
AuditedEmbeddableWithDeclaredData.class,
|
||||||
|
AuditedEmbeddableWithNoDeclaredData.class,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue