diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java index 266a017230..6a84daea58 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java @@ -24,12 +24,8 @@ package org.hibernate.metamodel.internal; import java.io.Serializable; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; - -import org.jboss.logging.Logger; - import org.hibernate.AssertionFailure; import org.hibernate.DuplicateMappingException; import org.hibernate.MappingException; @@ -48,10 +44,7 @@ import org.hibernate.internal.util.Value; import org.hibernate.metamodel.MetadataSourceProcessingOrder; import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.SessionFactoryBuilder; -import org.hibernate.metamodel.internal.source.AssociationResolver; import org.hibernate.metamodel.internal.source.Binder; -import org.hibernate.metamodel.internal.source.HibernateTypeResolver; -import org.hibernate.metamodel.internal.source.IdentifierGeneratorResolver; import org.hibernate.metamodel.internal.source.annotations.AnnotationMetadataSourceProcessorImpl; import org.hibernate.metamodel.internal.source.hbm.HbmMetadataSourceProcessorImpl; import org.hibernate.metamodel.spi.MetadataSourceProcessor; @@ -64,7 +57,6 @@ import org.hibernate.metamodel.spi.binding.TypeDefinition; import org.hibernate.metamodel.spi.domain.BasicType; import org.hibernate.metamodel.spi.domain.Type; import org.hibernate.metamodel.spi.relational.Database; -import org.hibernate.metamodel.spi.source.EntityHierarchy; import org.hibernate.metamodel.spi.source.FilterDefinitionSource; import org.hibernate.metamodel.spi.source.MappingDefaults; import org.hibernate.metamodel.spi.source.MetaAttributeContext; @@ -74,6 +66,7 @@ import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.type.TypeResolver; +import org.jboss.logging.Logger; /** * Container for configuration data collected during binding the metamodel. @@ -161,18 +154,9 @@ public class MetadataImpl implements MetadataImplementor, Serializable { processTypeDefinitions( metadataSourceProcessors ); processFilterDefinitions( metadataSourceProcessors ); - processIdentifierGenerators( metadataSourceProcessors ); - processMappings( metadataSourceProcessors ); - bindMappingDependentMetadata( metadataSourceProcessors ); - - // todo : remove this by coordinated ordering of entity processing - new AssociationResolver( this ).resolve(); - new HibernateTypeResolver( this ).resolve(); - // IdentifierGeneratorResolver.resolve() must execute after AttributeTypeResolver.resolve() - new IdentifierGeneratorResolver( this ).resolve(); } @@ -254,20 +238,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } private void processMappings(MetadataSourceProcessor[] metadataSourceProcessors) { - final ArrayList processedEntityNames = new ArrayList(); - final Binder binder = new Binder( this, processedEntityNames ); - for ( MetadataSourceProcessor processor : metadataSourceProcessors ) { - for ( EntityHierarchy entityHierarchy : processor.extractEntityHierarchies() ) { - binder.processEntityHierarchy( entityHierarchy ); - } - } + final Binder binder = new Binder( this ); + for ( MetadataSourceProcessor processor : metadataSourceProcessors ) + binder.processEntityHierarchies( processor.extractEntityHierarchies() ); } - - - - - private void bindMappingDependentMetadata(MetadataSourceProcessor[] metadataSourceProcessors) { for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) { metadataSourceProcessor.processMappingDependentMetadata(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java index b2e24cd094..bafdbef53a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java @@ -33,12 +33,16 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; - +import java.util.Properties; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.TruthValue; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.beans.BeanInfoHelper; @@ -48,7 +52,6 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBindingContainer; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding; -import org.hibernate.metamodel.spi.binding.CollectionLaziness; import org.hibernate.metamodel.spi.binding.ComponentAttributeBinding; import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityDiscriminator; @@ -59,6 +62,7 @@ import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.spi.binding.MetaAttribute; import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature; import org.hibernate.metamodel.spi.binding.SimpleValueBinding; +import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.binding.TypeDefinition; import org.hibernate.metamodel.spi.domain.Attribute; @@ -67,6 +71,7 @@ import org.hibernate.metamodel.spi.domain.Entity; import org.hibernate.metamodel.spi.domain.PluralAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.relational.Column; +import org.hibernate.metamodel.spi.relational.Datatype; import org.hibernate.metamodel.spi.relational.DerivedValue; import org.hibernate.metamodel.spi.relational.ForeignKey; import org.hibernate.metamodel.spi.relational.Identifier; @@ -112,41 +117,77 @@ import org.hibernate.metamodel.spi.source.ToOneAttributeSource; import org.hibernate.metamodel.spi.source.UniqueConstraintSource; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.service.config.spi.ConfigurationService; import org.hibernate.tuple.entity.EntityTuplizer; +import org.hibernate.type.Type; /** * The common binder shared between annotations and {@code hbm.xml} processing. *

- * The API consists of {@link #Binder(MetadataImplementor, List)} and {@link #processEntityHierarchy(EntityHierarchy)} + * The API consists of {@link #Binder( MetadataImplementor )} and {@link #processEntityHierarchies(Iterable)} * * @author Steve Ebersole * @author Hardy Ferentschik */ public class Binder { private final MetadataImplementor metadata; - private final List processedEntityNames; + private final ArrayList processedEntityNames = new ArrayList(); private InheritanceType currentInheritanceType; private EntityMode currentHierarchyEntityMode; private LocalBindingContext currentBindingContext; + private HashMap sourcesByName = new HashMap(); - public Binder(MetadataImplementor metadata, List processedEntityNames) { + public Binder( MetadataImplementor metadata ) { this.metadata = metadata; - this.processedEntityNames = processedEntityNames; } /** * Process an entity hierarchy. * - * @param entityHierarchy THe hierarchy to process. + * @param entityHierarchies THe hierarchies to process. */ - public void processEntityHierarchy(EntityHierarchy entityHierarchy) { - currentInheritanceType = entityHierarchy.getHierarchyInheritanceType(); - EntityBinding rootEntityBinding = createEntityBinding( entityHierarchy.getRootEntitySource(), null ); - if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) { - processHierarchySubEntities( entityHierarchy.getRootEntitySource(), rootEntityBinding ); - } - currentHierarchyEntityMode = null; + public void processEntityHierarchies( Iterable entityHierarchies ) { + // Index sources by name so we can find and resolve entities on the fly as references to them are encountered (e.g., within associations) + for ( EntityHierarchy hierarchy : entityHierarchies ) + mapSourcesByName( hierarchy.getRootEntitySource() ); + + for ( EntityHierarchy hierarchy : entityHierarchies ) { + currentInheritanceType = hierarchy.getHierarchyInheritanceType(); + RootEntitySource rootEntitySource = hierarchy.getRootEntitySource(); + EntityBinding rootEntityBinding = createEntityBinding( rootEntitySource, null ); + // Create identifier generator for root entity + Properties properties = new Properties(); + properties.putAll( metadata.getServiceRegistry().getService( ConfigurationService.class ).getSettings() ); + // TODO: where should these be added??? + if ( !properties.contains( AvailableSettings.PREFER_POOLED_VALUES_LO ) ) + properties.put( AvailableSettings.PREFER_POOLED_VALUES_LO, "false" ); + if ( !properties.contains( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER ) ) + properties.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, new ObjectNameNormalizer() { + + @Override + protected boolean isUseQuotedIdentifiersGlobally() { + return metadata.isGloballyQuotedIdentifiers(); + } + + @Override + protected NamingStrategy getNamingStrategy() { + return metadata.getNamingStrategy(); + } + } ); + rootEntityBinding.getHierarchyDetails().getEntityIdentifier(). + createIdentifierGenerator( metadata.getIdentifierGeneratorFactory(), properties ); + + if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) + processHierarchySubEntities( rootEntitySource, rootEntityBinding ); + currentHierarchyEntityMode = null; + } + } + + private void mapSourcesByName( EntitySource source ) { + sourcesByName.put( source.getEntityName(), source ); + for ( SubclassEntitySource subsource : source.subclassEntitySources() ) + mapSourcesByName( subsource ); } private void processHierarchySubEntities(SubclassEntityContainer subclassEntitySource, EntityBinding superEntityBinding) { @@ -455,6 +496,7 @@ public class Binder { entityBinding.getHierarchyDetails().setEntityDiscriminator( discriminator ); entityBinding.setDiscriminatorMatchValue( entitySource.getDiscriminatorMatchValue() ); + resolveTypeInformation(discriminator.getExplicitHibernateTypeDescriptor(), relationalValue); } private void bindDiscriminatorValue(SubclassEntitySource entitySource, EntityBinding entityBinding) { @@ -466,7 +508,7 @@ public class Binder { } private void bindAttributes( - AttributeSourceContainer attributeSourceContainer, + AttributeSourceContainer attributeSourceContainer, AttributeBindingContainer attributeBindingContainer, Deque tableStack) { // todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes. @@ -603,26 +645,26 @@ public class Binder { doBasicAttributeBinding( source, binding ); } - private CollectionLaziness interpretLaziness(String laziness) { - if ( laziness == null ) { - laziness = Boolean.toString( metadata.getMappingDefaults().areAssociationsLazy() ); - } - - if ( "extra".equals( laziness ) ) { - return CollectionLaziness.EXTRA; - } - else if ( "false".equals( laziness ) ) { - return CollectionLaziness.NOT; - } - else if ( "true".equals( laziness ) ) { - return CollectionLaziness.LAZY; - } - - throw new MappingException( - String.format( "Unexpected collection laziness value %s", laziness ), - currentBindingContext.getOrigin() - ); - } +// private CollectionLaziness interpretLaziness(String laziness) { +// if ( laziness == null ) { +// laziness = Boolean.toString( metadata.getMappingDefaults().areAssociationsLazy() ); +// } +// +// if ( "extra".equals( laziness ) ) { +// return CollectionLaziness.EXTRA; +// } +// else if ( "false".equals( laziness ) ) { +// return CollectionLaziness.NOT; +// } +// else if ( "true".equals( laziness ) ) { +// return CollectionLaziness.LAZY; +// } +// +// throw new MappingException( +// String.format( "Unexpected collection laziness value %s", laziness ), +// currentBindingContext.getOrigin() +// ); +// } private void bindCollectionTable( PluralAttributeSource attributeSource, @@ -688,7 +730,7 @@ public class Binder { AbstractPluralAttributeBinding pluralAttributeBinding, Deque tableStack) { - TableSpecification targetTable = tableStack.peekLast(); +// TableSpecification targetTable = tableStack.peekLast(); pluralAttributeBinding.getPluralAttributeKeyBinding().prepareForeignKey( attributeSource.getKeySource().getExplicitForeignKeyName(), //tableStack.peekLast().getLogicalName() @@ -885,21 +927,11 @@ public class Binder { } final BasicAttributeBinding attributeBinding; - if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) { + if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) attributeBinding = attributeBindingContainer.makeBasicAttributeBinding( attribute ); - resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); - } - else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) { + else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) attributeBinding = attributeBindingContainer.makeManyToOneAttributeBinding( attribute ); - resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); - resolveToOneInformation( - (ToOneAttributeSource) attributeSource, - (ManyToOneAttributeBinding) attributeBinding - ); - } - else { - throw new NotYetImplementedException(); - } + else throw new NotYetImplementedException(); attributeBinding.setGeneration( attributeSource.getGeneration() ); attributeBinding.setLazy( attributeSource.isLazy() ); @@ -915,6 +947,25 @@ public class Binder { bindRelationalValues( attributeSource, attributeBinding ); + resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); + if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) + resolveToOneInformation( ( ToOneAttributeSource ) attributeSource, ( ManyToOneAttributeBinding ) attributeBinding ); + + if ( attributeBinding instanceof SingularAssociationAttributeBinding ) { + SingularAssociationAttributeBinding assocAttrBinding = ( SingularAssociationAttributeBinding ) attributeBinding; + String referencedEntityName = assocAttrBinding.getReferencedEntityName(); + EntityBinding referencedEntityBinding = getEntityBinding( referencedEntityName ); + if (referencedEntityBinding == null) { + EntitySource source = sourcesByName.get(referencedEntityName); + createEntityBinding(source, referencedEntityBinding); + } + AttributeBinding referencedAttrBinding = assocAttrBinding.isPropertyReference() ? + referencedEntityBinding.locateAttributeBinding( assocAttrBinding.getReferencedAttributeName() ) : + referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(); + assocAttrBinding.resolveReference( referencedAttrBinding ); + referencedAttrBinding.addEntityReferencingAttributeBinding( assocAttrBinding ); + } + attributeBinding.setMetaAttributeContext( buildMetaAttributeContext( attributeSource.metaAttributes(), @@ -925,6 +976,24 @@ public class Binder { return attributeBinding; } + private EntityBinding getEntityBinding( String entityName ) { + // Check if binding has already been created + EntityBinding binding = metadata.getEntityBinding( entityName ); + if ( binding == null ) { + // Find appropriate source to create binding + EntitySource source = sourcesByName.get( entityName ); + // Get super entity binding (creating it if necessary using recursive call to this method) + EntityBinding superBinding = source instanceof SubclassEntitySource + ? getEntityBinding( ( ( SubclassEntitySource ) source ).superclassEntitySource().getEntityName() ) + : null; + // Create entity binding + binding = createEntityBinding( source, superBinding ); + // Create entity binding's sub-entity bindings + processHierarchySubEntities( source, binding ); + } + return binding; + } + private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, BasicAttributeBinding attributeBinding) { final Class attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); if ( attributeJavaType != null ) { @@ -933,6 +1002,7 @@ public class Binder { } resolveTypeInformation( typeSource, attributeBinding.getHibernateTypeDescriptor(), attributeJavaType ); + resolveTypeInformation( attributeBinding.getHibernateTypeDescriptor(), (SimpleValue)attributeBinding.getValue() ); } private void resolveTypeInformation( @@ -975,6 +1045,29 @@ public class Binder { } } + private void resolveTypeInformation( HibernateTypeDescriptor descriptor, + SimpleValue value ) { + Type resolvedType = descriptor.getResolvedTypeMapping(); + if ( resolvedType == null ) { + final String name = descriptor.getExplicitTypeName() == null ? descriptor.getJavaTypeName() : descriptor.getExplicitTypeName(); + if (name != null) { + resolvedType = metadata.getTypeResolver().heuristicType( name, convertTypeParametersToProperties( descriptor ) ); + descriptor.setResolvedTypeMapping( resolvedType ); + } + if (resolvedType == null) return; + } + if ( descriptor.getJavaTypeName() == null ) descriptor.setJavaTypeName( resolvedType.getReturnedClass().getName() ); + if ( value.getDatatype() == null ) + value.setDatatype( new Datatype( resolvedType.sqlTypes( metadata )[0], resolvedType.getName(), + resolvedType.getReturnedClass() ) ); + } + + private Properties convertTypeParametersToProperties( HibernateTypeDescriptor descriptor ) { + Properties props = new Properties( ); + if ( descriptor.getTypeParameters() != null ) props.putAll( descriptor.getTypeParameters() ); + return props; + } + /** * @param attribute the domain attribute * diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeResolver.java index 5a45c693c8..6647714d40 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeResolver.java @@ -64,11 +64,13 @@ public class HibernateTypeResolver { } for ( AttributeBinding attributeBinding : entityBinding.attributeBindings() ) { if ( SingularAttributeBinding.class.isInstance( attributeBinding ) ) { + System.out.println("singlular binding: " + attributeBinding.getAttribute().getName()); resolveSingularAttributeTypeInformation( SingularAttributeBinding.class.cast( attributeBinding ) ); } else if ( AbstractPluralAttributeBinding.class.isInstance( attributeBinding ) ) { + System.out.println("plural binding: " + attributeBinding.getAttribute().getName()); resolvePluralAttributeTypeInformation( AbstractPluralAttributeBinding.class.cast( attributeBinding ) ); @@ -126,6 +128,7 @@ public class HibernateTypeResolver { // 2) we know the java type of the attribute Type resolvedType; resolvedType = determineSingularTypeFromDescriptor( attributeBinding.getHibernateTypeDescriptor() ); + System.out.println("resolvedType: " + resolvedType); if ( resolvedType == null ) { if ( ! attributeBinding.getAttribute().isSingular() ) { throw new AssertionFailure( "SingularAttributeBinding object has a plural attribute: " + attributeBinding.getAttribute().getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/EntityHierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/EntityHierarchyBuilder.java index d8506fdf79..4f99c0ce95 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/EntityHierarchyBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/EntityHierarchyBuilder.java @@ -144,7 +144,7 @@ public class EntityHierarchyBuilder { hierarchyInheritanceType, bindingContext ); - SubclassEntitySource subclassEntitySource = new SubclassEntitySourceImpl( subclassEntityClass ); + SubclassEntitySource subclassEntitySource = new SubclassEntitySourceImpl( subclassEntityClass, entitySource ); entitySource.add( subclassEntitySource ); addSubclassEntitySources( bindingContext, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/SubclassEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/SubclassEntitySourceImpl.java index 38d7be0657..07060c55a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/SubclassEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/SubclassEntitySourceImpl.java @@ -23,15 +23,31 @@ */ package org.hibernate.metamodel.internal.source.annotations.entity; +import org.hibernate.metamodel.spi.source.EntitySource; import org.hibernate.metamodel.spi.source.SubclassEntitySource; /** * @author Hardy Ferentschik */ public class SubclassEntitySourceImpl extends EntitySourceImpl implements SubclassEntitySource { - public SubclassEntitySourceImpl(EntityClass entityClass) { + + private final EntitySource container; + + public SubclassEntitySourceImpl( EntityClass entityClass, + EntitySource container ) { super( entityClass ); + this.container = container; } + + /** + * {@inheritDoc} + * + * @see org.hibernate.metamodel.spi.source.SubclassEntitySource#superclassEntitySource() + */ + @Override + public EntitySource superclassEntitySource() { + return container; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/HierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/HierarchyBuilder.java index 8e945caf9d..3c5f7bed95 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/HierarchyBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/HierarchyBuilder.java @@ -36,6 +36,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbJoinedSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbUnionSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.SubEntityElement; +import org.hibernate.metamodel.spi.source.EntitySource; import org.hibernate.metamodel.spi.source.SubclassEntityContainer; import org.hibernate.metamodel.spi.source.SubclassEntitySource; @@ -81,14 +82,14 @@ public class HierarchyBuilder { else { // we have to see if this things super-type has been found yet, and if not add it to the // extends queue - final SubclassEntitySourceImpl subClassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, entityElement ); + final String entityItExtends = + currentMappingDocument.getMappingLocalBindingContext(). + qualifyClassName( ( (SubEntityElement) entityElement ).getExtends() ); + final SubclassEntityContainer container = subEntityContainerMap.get( entityItExtends ); + final SubclassEntitySourceImpl subClassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, entityElement, ( EntitySource ) container ); final String entityName = subClassEntitySource.getEntityName(); subEntityContainerMap.put( entityName, subClassEntitySource ); - final String entityItExtends = currentMappingDocument.getMappingLocalBindingContext().qualifyClassName( - ((SubEntityElement) entityElement).getExtends() - ); processSubElements( entityElement, subClassEntitySource ); - final SubclassEntityContainer container = subEntityContainerMap.get( entityItExtends ); if ( container != null ) { // we already have this entity's super, attach it and continue container.add( subClassEntitySource ); @@ -150,7 +151,7 @@ public class HierarchyBuilder { private void processElements(List subElements, SubclassEntityContainer container) { for ( Object subElementO : subElements ) { final SubEntityElement subElement = (SubEntityElement) subElementO; - final SubclassEntitySourceImpl subclassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, subElement ); + final SubclassEntitySourceImpl subclassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, subElement, ( EntitySource ) container ); container.add( subclassEntitySource ); final String subEntityName = subclassEntitySource.getEntityName(); subEntityContainerMap.put( subEntityName, subclassEntitySource ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SubclassEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SubclassEntitySourceImpl.java index d0d37b639c..6bfa64f569 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SubclassEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SubclassEntitySourceImpl.java @@ -27,6 +27,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.EntityElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbJoinedSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbUnionSubclassElement; +import org.hibernate.metamodel.spi.source.EntitySource; import org.hibernate.metamodel.spi.source.SubclassEntitySource; import org.hibernate.metamodel.spi.source.TableSource; @@ -34,8 +35,14 @@ import org.hibernate.metamodel.spi.source.TableSource; * @author Steve Ebersole */ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implements SubclassEntitySource { - protected SubclassEntitySourceImpl(MappingDocument sourceMappingDocument, EntityElement entityElement) { + + private final EntitySource container; + + protected SubclassEntitySourceImpl( MappingDocument sourceMappingDocument, + EntityElement entityElement, + EntitySource container ) { super( sourceMappingDocument, entityElement ); + this.container = container; } @Override @@ -97,4 +104,14 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement ? ( (JaxbSubclassElement) entityElement() ).getDiscriminatorValue() : null; } + + /** + * {@inheritDoc} + * + * @see SubclassEntitySource#superclassEntitySource() + */ + @Override + public EntitySource superclassEntitySource() { + return container; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SubclassEntitySource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SubclassEntitySource.java index f43ecdccd2..d2a3914439 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SubclassEntitySource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SubclassEntitySource.java @@ -27,4 +27,9 @@ package org.hibernate.metamodel.spi.source; * @author Steve Ebersole */ public interface SubclassEntitySource extends EntitySource { + + /** + * @return the entity source for the entity that is a superclass of the entity for which this is a source + */ + EntitySource superclassEntitySource(); }