HHH-16491 Special handling for generic component properties
This commit is contained in:
parent
5c2657d27c
commit
725c292227
|
@ -141,6 +141,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
|
||||||
|
|
||||||
private final Map<String,PersistentClass> entityBindingMap = new HashMap<>();
|
private final Map<String,PersistentClass> entityBindingMap = new HashMap<>();
|
||||||
private final List<Component> composites = new ArrayList<>();
|
private final List<Component> composites = new ArrayList<>();
|
||||||
|
private final Map<Class<?>, Component> genericComponentsMap = new HashMap<>();
|
||||||
private final Map<String,Collection> collectionBindingMap = new HashMap<>();
|
private final Map<String,Collection> collectionBindingMap = new HashMap<>();
|
||||||
|
|
||||||
private final Map<String, FilterDefinition> filterDefinitionMap = new HashMap<>();
|
private final Map<String, FilterDefinition> filterDefinitionMap = new HashMap<>();
|
||||||
|
@ -282,6 +283,16 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
|
||||||
composites.forEach( consumer );
|
composites.forEach( consumer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerGenericComponent(Component component) {
|
||||||
|
genericComponentsMap.put( component.getComponentClass(), component );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getGenericComponent(Class<?> componentClass) {
|
||||||
|
return genericComponentsMap.get( componentClass );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionFactoryBuilder getSessionFactoryBuilder() {
|
public SessionFactoryBuilder getSessionFactoryBuilder() {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
@ -2314,6 +2325,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
|
||||||
options,
|
options,
|
||||||
entityBindingMap,
|
entityBindingMap,
|
||||||
composites,
|
composites,
|
||||||
|
genericComponentsMap,
|
||||||
mappedSuperClasses,
|
mappedSuperClasses,
|
||||||
collectionBindingMap,
|
collectionBindingMap,
|
||||||
typeDefRegistry.copyRegistrationMap(),
|
typeDefRegistry.copyRegistrationMap(),
|
||||||
|
|
|
@ -90,6 +90,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
|
|
||||||
private final Map<String,PersistentClass> entityBindingMap;
|
private final Map<String,PersistentClass> entityBindingMap;
|
||||||
private final List<Component> composites;
|
private final List<Component> composites;
|
||||||
|
private final Map<Class<?>, Component> genericComponentsMap;
|
||||||
private final Map<Class<?>, MappedSuperclass> mappedSuperclassMap;
|
private final Map<Class<?>, MappedSuperclass> mappedSuperclassMap;
|
||||||
private final Map<String,Collection> collectionBindingMap;
|
private final Map<String,Collection> collectionBindingMap;
|
||||||
private final Map<String, TypeDefinition> typeDefinitionMap;
|
private final Map<String, TypeDefinition> typeDefinitionMap;
|
||||||
|
@ -110,6 +111,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
MetadataBuildingOptions metadataBuildingOptions,
|
MetadataBuildingOptions metadataBuildingOptions,
|
||||||
Map<String, PersistentClass> entityBindingMap,
|
Map<String, PersistentClass> entityBindingMap,
|
||||||
List<Component> composites,
|
List<Component> composites,
|
||||||
|
Map<Class<?>, Component> genericComponentsMap,
|
||||||
Map<Class<?>, MappedSuperclass> mappedSuperclassMap,
|
Map<Class<?>, MappedSuperclass> mappedSuperclassMap,
|
||||||
Map<String, Collection> collectionBindingMap,
|
Map<String, Collection> collectionBindingMap,
|
||||||
Map<String, TypeDefinition> typeDefinitionMap,
|
Map<String, TypeDefinition> typeDefinitionMap,
|
||||||
|
@ -129,6 +131,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
this.metadataBuildingOptions = metadataBuildingOptions;
|
this.metadataBuildingOptions = metadataBuildingOptions;
|
||||||
this.entityBindingMap = entityBindingMap;
|
this.entityBindingMap = entityBindingMap;
|
||||||
this.composites = composites;
|
this.composites = composites;
|
||||||
|
this.genericComponentsMap = genericComponentsMap;
|
||||||
this.mappedSuperclassMap = mappedSuperclassMap;
|
this.mappedSuperclassMap = mappedSuperclassMap;
|
||||||
this.collectionBindingMap = collectionBindingMap;
|
this.collectionBindingMap = collectionBindingMap;
|
||||||
this.typeDefinitionMap = typeDefinitionMap;
|
this.typeDefinitionMap = typeDefinitionMap;
|
||||||
|
@ -570,6 +573,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
composites.forEach( consumer );
|
composites.forEach( consumer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getGenericComponent(Class<?> componentClass) {
|
||||||
|
return genericComponentsMap.get( componentClass );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.hibernate.type.Type getIdentifierType(String entityName) throws MappingException {
|
public org.hibernate.type.Type getIdentifierType(String entityName) throws MappingException {
|
||||||
final PersistentClass pc = entityBindingMap.get( entityName );
|
final PersistentClass pc = entityBindingMap.get( entityName );
|
||||||
|
|
|
@ -229,7 +229,39 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
return join;
|
return join;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embeddable classes can be defined using generics. For this reason, we must check
|
||||||
|
* every property value and specially handle generic components by setting the property
|
||||||
|
* as generic, to later be able to resolve its concrete type, and creating a new component
|
||||||
|
* with correctly typed sub-properties for the metamodel.
|
||||||
|
*/
|
||||||
|
public static void handleGenericComponentProperty(Property property, MetadataBuildingContext context) {
|
||||||
|
final Value value = property.getValue();
|
||||||
|
if ( value instanceof Component ) {
|
||||||
|
final Component component = (Component) value;
|
||||||
|
if ( component.isGeneric() && context.getMetadataCollector()
|
||||||
|
.getGenericComponent( component.getComponentClass() ) == null ) {
|
||||||
|
// If we didn't already, register the generic component to use it later
|
||||||
|
// as the metamodel type for generic embeddable attributes
|
||||||
|
final Component copy = component.copy();
|
||||||
|
copy.setGeneric( false );
|
||||||
|
copy.getProperties().clear();
|
||||||
|
for ( Property prop : component.getProperties() ) {
|
||||||
|
prepareActualProperty(
|
||||||
|
prop,
|
||||||
|
component.getComponentClass(),
|
||||||
|
true,
|
||||||
|
context,
|
||||||
|
copy::addProperty
|
||||||
|
);
|
||||||
|
}
|
||||||
|
context.getMetadataCollector().registerGenericComponent( copy );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addPropertyToPersistentClass(Property property, XClass declaringClass) {
|
private void addPropertyToPersistentClass(Property property, XClass declaringClass) {
|
||||||
|
handleGenericComponentProperty( property, getContext() );
|
||||||
if ( declaringClass != null ) {
|
if ( declaringClass != null ) {
|
||||||
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
|
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
|
||||||
if ( inheritanceState == null ) {
|
if ( inheritanceState == null ) {
|
||||||
|
@ -253,10 +285,10 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
|
private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
|
||||||
final Class<?> type = getContext().getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
final Class<?> type = getContext().getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
||||||
final MappedSuperclass superclass = getContext().getMetadataCollector().getMappedSuperclass( type );
|
final MappedSuperclass superclass = getContext().getMetadataCollector().getMappedSuperclass( type );
|
||||||
prepareActualPropertyForSuperclass( prop, type, true, getContext(), superclass::addDeclaredProperty );
|
prepareActualProperty( prop, type, true, getContext(), superclass::addDeclaredProperty );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepareActualPropertyForSuperclass(
|
static void prepareActualProperty(
|
||||||
Property prop,
|
Property prop,
|
||||||
Class<?> type,
|
Class<?> type,
|
||||||
boolean allowCollections,
|
boolean allowCollections,
|
||||||
|
@ -322,14 +354,20 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
}
|
}
|
||||||
if ( value instanceof Component ) {
|
if ( value instanceof Component ) {
|
||||||
final Component component = ( (Component) value );
|
final Component component = ( (Component) value );
|
||||||
final Iterator<Property> propertyIterator = component.getPropertyIterator();
|
final Class<?> componentClass = component.getComponentClass();
|
||||||
while ( propertyIterator.hasNext() ) {
|
if ( component.isGeneric() ) {
|
||||||
Property property = propertyIterator.next();
|
actualProperty.setValue( context.getMetadataCollector().getGenericComponent( componentClass ) );
|
||||||
try {
|
}
|
||||||
property.getGetter( component.getComponentClass() );
|
else {
|
||||||
}
|
final Iterator<Property> propertyIterator = component.getPropertyIterator();
|
||||||
catch (PropertyNotFoundException e) {
|
while ( propertyIterator.hasNext() ) {
|
||||||
propertyIterator.remove();
|
Property property = propertyIterator.next();
|
||||||
|
try {
|
||||||
|
property.getGetter( componentClass );
|
||||||
|
}
|
||||||
|
catch (PropertyNotFoundException e) {
|
||||||
|
propertyIterator.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,9 +404,8 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
||||||
}
|
}
|
||||||
else if ( value instanceof Component ) {
|
else if ( value instanceof Component ) {
|
||||||
final Component component = (Component) value;
|
final Component component = (Component) value;
|
||||||
// Avoid setting component class name to java.lang.Object
|
// Avoid setting type name for generic components
|
||||||
// for embeddable types with generic type parameters
|
if ( !component.isGeneric() ) {
|
||||||
if ( !typeName.equals( Object.class.getName() ) ) {
|
|
||||||
component.setComponentClassName( typeName );
|
component.setComponentClassName( typeName );
|
||||||
}
|
}
|
||||||
if ( component.getTypeName() != null ) {
|
if ( component.getTypeName() != null ) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.boot.model.internal;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ import jakarta.persistence.Version;
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.annotations.Any;
|
import org.hibernate.annotations.Any;
|
||||||
import org.hibernate.annotations.AttributeBinderType;
|
import org.hibernate.annotations.AttributeBinderType;
|
||||||
import org.hibernate.annotations.CompositeType;
|
import org.hibernate.annotations.CompositeType;
|
||||||
|
@ -71,6 +69,8 @@ import static jakarta.persistence.FetchType.LAZY;
|
||||||
import static org.hibernate.boot.model.internal.AnyBinder.bindAny;
|
import static org.hibernate.boot.model.internal.AnyBinder.bindAny;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId;
|
import static org.hibernate.boot.model.internal.BinderHelper.isCompositeId;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
|
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
|
||||||
|
import static org.hibernate.boot.model.internal.ClassPropertyHolder.handleGenericComponentProperty;
|
||||||
|
import static org.hibernate.boot.model.internal.ClassPropertyHolder.prepareActualProperty;
|
||||||
import static org.hibernate.boot.model.internal.CollectionBinder.bindCollection;
|
import static org.hibernate.boot.model.internal.CollectionBinder.bindCollection;
|
||||||
import static org.hibernate.boot.model.internal.GeneratorBinder.createForeignGenerator;
|
import static org.hibernate.boot.model.internal.GeneratorBinder.createForeignGenerator;
|
||||||
import static org.hibernate.boot.model.internal.GeneratorBinder.createIdGenerator;
|
import static org.hibernate.boot.model.internal.GeneratorBinder.createIdGenerator;
|
||||||
|
@ -339,18 +339,13 @@ public class PropertyBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDeclaredIdentifier(RootClass rootClass, MappedSuperclass superclass, Property prop) {
|
private void setDeclaredIdentifier(RootClass rootClass, MappedSuperclass superclass, Property prop) {
|
||||||
|
handleGenericComponentProperty( prop, buildingContext );
|
||||||
if ( superclass == null ) {
|
if ( superclass == null ) {
|
||||||
rootClass.setDeclaredIdentifierProperty( prop );
|
rootClass.setDeclaredIdentifierProperty( prop );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Class<?> type = buildingContext.getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
final Class<?> type = buildingContext.getBootstrapContext().getReflectionManager().toClass( declaringClass );
|
||||||
ClassPropertyHolder.prepareActualPropertyForSuperclass(
|
prepareActualProperty( prop, type, false, buildingContext, superclass::setDeclaredIdentifierProperty );
|
||||||
prop,
|
|
||||||
type,
|
|
||||||
false,
|
|
||||||
buildingContext,
|
|
||||||
superclass::setDeclaredIdentifierProperty
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component getOrCreateCompositeId(RootClass rootClass) {
|
private Component getOrCreateCompositeId(RootClass rootClass) {
|
||||||
|
|
|
@ -244,6 +244,10 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor
|
||||||
delegate().visitRegisteredComponents( consumer );
|
delegate().visitRegisteredComponents( consumer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getGenericComponent(Class<?> componentClass) {
|
||||||
|
return delegate().getGenericComponent( componentClass );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
|
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
|
||||||
|
|
|
@ -83,6 +83,8 @@ public interface InFlightMetadataCollector extends MetadataImplementor {
|
||||||
|
|
||||||
void registerComponent(Component component);
|
void registerComponent(Component component);
|
||||||
|
|
||||||
|
void registerGenericComponent(Component component);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an import (for use in HQL).
|
* Adds an import (for use in HQL).
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,4 +56,6 @@ public interface MetadataImplementor extends Metadata {
|
||||||
void initSessionFactory(SessionFactoryImplementor sessionFactoryImplementor);
|
void initSessionFactory(SessionFactoryImplementor sessionFactoryImplementor);
|
||||||
|
|
||||||
void visitRegisteredComponents(Consumer<Component> consumer);
|
void visitRegisteredComponents(Consumer<Component> consumer);
|
||||||
|
|
||||||
|
Component getGenericComponent(Class<?> componentClass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
private PersistentClass owner;
|
private PersistentClass owner;
|
||||||
private boolean dynamic;
|
private boolean dynamic;
|
||||||
private boolean isKey;
|
private boolean isKey;
|
||||||
|
private Boolean isGeneric;
|
||||||
private String roleName;
|
private String roleName;
|
||||||
|
|
||||||
private final ArrayList<Property> properties = new ArrayList<>();
|
private final ArrayList<Property> properties = new ArrayList<>();
|
||||||
|
@ -123,6 +124,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
this.parentProperty = original.parentProperty;
|
this.parentProperty = original.parentProperty;
|
||||||
this.owner = original.owner;
|
this.owner = original.owner;
|
||||||
this.dynamic = original.dynamic;
|
this.dynamic = original.dynamic;
|
||||||
|
this.isGeneric = original.isGeneric;
|
||||||
this.metaAttributes = original.metaAttributes == null ? null : new HashMap<>( original.metaAttributes );
|
this.metaAttributes = original.metaAttributes == null ? null : new HashMap<>( original.metaAttributes );
|
||||||
this.isKey = original.isKey;
|
this.isKey = original.isKey;
|
||||||
this.roleName = original.roleName;
|
this.roleName = original.roleName;
|
||||||
|
@ -819,4 +821,15 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
public void setStructColumnNames(String[] structColumnNames) {
|
public void setStructColumnNames(String[] structColumnNames) {
|
||||||
this.structColumnNames = structColumnNames;
|
this.structColumnNames = structColumnNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGeneric() {
|
||||||
|
if ( isGeneric == null ) {
|
||||||
|
isGeneric = getComponentClassName() != null && getComponentClass().getTypeParameters().length != 0;
|
||||||
|
}
|
||||||
|
return isGeneric;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGeneric(boolean generic) {
|
||||||
|
isGeneric = generic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,9 +300,11 @@ public class AttributeFactory {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Class<Y> embeddableClass = (Class<Y>) component.getComponentClass();
|
final Class<Y> embeddableClass = (Class<Y>) component.getComponentClass();
|
||||||
|
|
||||||
final EmbeddableDomainType<Y> cached = context.locateEmbeddable( embeddableClass, component );
|
if ( !component.isGeneric() ) {
|
||||||
if ( cached != null ) {
|
final EmbeddableDomainType<Y> cached = context.locateEmbeddable( embeddableClass, component );
|
||||||
return cached;
|
if ( cached != null ) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final JavaTypeRegistry registry = context.getTypeConfiguration()
|
final JavaTypeRegistry registry = context.getTypeConfiguration()
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
|
@ -27,6 +28,7 @@ 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;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.metamodel.MappingMetamodel;
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
|
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
|
||||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||||
|
@ -251,6 +253,33 @@ public class MetadataContext {
|
||||||
return Collections.unmodifiableMap( identifiableTypesByName );
|
return Collections.unmodifiableMap( identifiableTypesByName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <X> PersistentAttribute<X, ?> buildAttribute(
|
||||||
|
Property property,
|
||||||
|
IdentifiableDomainType<X> entityType,
|
||||||
|
BiFunction<IdentifiableDomainType<X>, Property, PersistentAttribute<X, ?>> factoryFunction) {
|
||||||
|
final PersistentAttribute<X, ?> attribute;
|
||||||
|
final Component component = property.getValue() instanceof Component ? (Component) property.getValue() : null;
|
||||||
|
if ( component != null && component.isGeneric() ) {
|
||||||
|
// This is an embeddable property that uses generics, we have to retrieve the generic
|
||||||
|
// component previously registered and create the concrete attribute
|
||||||
|
final Component genericComponent = runtimeModelCreationContext.getMetadata()
|
||||||
|
.getGenericComponent( component.getComponentClass() );
|
||||||
|
final Property genericProperty = property.copy();
|
||||||
|
genericProperty.setValue( genericComponent );
|
||||||
|
genericProperty.setGeneric( true );
|
||||||
|
attribute = factoryFunction.apply( entityType, genericProperty );
|
||||||
|
if ( !property.isGeneric() ) {
|
||||||
|
final PersistentAttribute<X, ?> concreteAttribute = factoryFunction.apply( entityType, property );
|
||||||
|
//noinspection unchecked
|
||||||
|
( (AttributeContainer<X>) entityType ).getInFlightAccess().addConcreteGenericAttribute( concreteAttribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
attribute = factoryFunction.apply( entityType, property );
|
||||||
|
}
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void wrapUp() {
|
public void wrapUp() {
|
||||||
if ( LOG.isTraceEnabled() ) {
|
if ( LOG.isTraceEnabled() ) {
|
||||||
|
@ -286,9 +315,10 @@ public class MetadataContext {
|
||||||
// skip the version property, it was already handled previously.
|
// skip the version property, it was already handled previously.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute(
|
final PersistentAttribute<Object, ?> attribute = buildAttribute(
|
||||||
|
property,
|
||||||
jpaMapping,
|
jpaMapping,
|
||||||
property
|
attributeFactory::buildAttribute
|
||||||
);
|
);
|
||||||
if ( attribute != null ) {
|
if ( attribute != null ) {
|
||||||
addAttribute( jpaMapping, attribute );
|
addAttribute( jpaMapping, attribute );
|
||||||
|
@ -329,7 +359,11 @@ public class MetadataContext {
|
||||||
// skip the version property, it was already handled previously.
|
// skip the version property, it was already handled previously.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( jpaType, property );
|
final PersistentAttribute<Object, ?> attribute = buildAttribute(
|
||||||
|
property,
|
||||||
|
jpaType,
|
||||||
|
attributeFactory::buildAttribute
|
||||||
|
);
|
||||||
if ( attribute != null ) {
|
if ( attribute != null ) {
|
||||||
addAttribute( jpaType, attribute );
|
addAttribute( jpaType, attribute );
|
||||||
if ( property.isNaturalIdentifier() ) {
|
if ( property.isNaturalIdentifier() ) {
|
||||||
|
@ -376,8 +410,9 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
( ( AttributeContainer<?>) embeddable ).getInFlightAccess().finishUp();
|
( ( AttributeContainer<?>) embeddable ).getInFlightAccess().finishUp();
|
||||||
// Do not process embeddables for entity types i.e. id-classes
|
// Do not process embeddables for entity types i.e. id-classes or
|
||||||
if ( !( embeddable.getExpressibleJavaType() instanceof EntityJavaType<?> ) ) {
|
// generic component embeddables used just for concrete type resolution
|
||||||
|
if ( !component.isGeneric() && !( embeddable.getExpressibleJavaType() instanceof EntityJavaType<?> ) ) {
|
||||||
embeddables.put( embeddable.getJavaType(), embeddable );
|
embeddables.put( embeddable.getJavaType(), embeddable );
|
||||||
|
|
||||||
if ( staticMetamodelScanEnabled ) {
|
if ( staticMetamodelScanEnabled ) {
|
||||||
|
@ -423,22 +458,26 @@ public class MetadataContext {
|
||||||
//noinspection rawtypes
|
//noinspection rawtypes
|
||||||
final AttributeContainer attributeContainer = (AttributeContainer) identifiableType;
|
final AttributeContainer attributeContainer = (AttributeContainer) identifiableType;
|
||||||
if ( declaredIdentifierProperty != null ) {
|
if ( declaredIdentifierProperty != null ) {
|
||||||
final SingularPersistentAttribute<?, Object> idAttribute = attributeFactory.buildIdAttribute(
|
//noinspection unchecked
|
||||||
|
final SingularPersistentAttribute<?, Object> idAttribute = (SingularPersistentAttribute<?, Object>) buildAttribute(
|
||||||
|
declaredIdentifierProperty,
|
||||||
identifiableType,
|
identifiableType,
|
||||||
declaredIdentifierProperty
|
attributeFactory::buildIdAttribute
|
||||||
);
|
);
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
||||||
}
|
}
|
||||||
final Property superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
|
else {
|
||||||
if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
|
final Property superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
|
||||||
// If the superclass identifier is generic we have to build the attribute to register the concrete type
|
if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
|
||||||
final SingularPersistentAttribute<?, Object> concreteIdentifier = attributeFactory.buildIdAttribute(
|
// If the superclass identifier is generic we have to build the attribute to register the concrete type
|
||||||
identifiableType,
|
final SingularPersistentAttribute<?, Object> concreteIdentifier = attributeFactory.buildIdAttribute(
|
||||||
persistentClass.getIdentifierProperty()
|
identifiableType,
|
||||||
);
|
persistentClass.getIdentifierProperty()
|
||||||
//noinspection unchecked
|
);
|
||||||
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
|
//noinspection unchecked
|
||||||
|
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -519,10 +558,14 @@ public class MetadataContext {
|
||||||
if ( mappingType.hasIdentifierProperty() ) {
|
if ( mappingType.hasIdentifierProperty() ) {
|
||||||
final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
|
final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
|
||||||
if ( declaredIdentifierProperty != null ) {
|
if ( declaredIdentifierProperty != null ) {
|
||||||
final SingularPersistentAttribute<X, Object> attribute =
|
|
||||||
attributeFactory.buildIdAttribute( jpaMappingType, declaredIdentifierProperty );
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
( ( AttributeContainer) jpaMappingType ).getInFlightAccess().applyIdAttribute( attribute );
|
final SingularPersistentAttribute<X, Object> attribute = (SingularPersistentAttribute<X, Object>) buildAttribute(
|
||||||
|
declaredIdentifierProperty,
|
||||||
|
jpaMappingType,
|
||||||
|
attributeFactory::buildIdAttribute
|
||||||
|
);
|
||||||
|
//noinspection unchecked
|
||||||
|
( (AttributeContainer<X>) jpaMappingType ).getInFlightAccess().applyIdAttribute( attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//a MappedSuperclass can have no identifier if the id is set below in the hierarchy
|
//a MappedSuperclass can have no identifier if the id is set below in the hierarchy
|
||||||
|
|
Loading…
Reference in New Issue