HHH-7048: Moved logic in resolvers to Binder and changed Binder.processMappings to receive all entity hierarchies at once to enable one-pass resolution of all entities and attributes.

This commit is contained in:
John Verhaeg 2012-02-09 12:07:40 -06:00
parent 50166f79bc
commit 3e96b29a3a
8 changed files with 197 additions and 87 deletions

View File

@ -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<String> processedEntityNames = new ArrayList<String>();
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();

View File

@ -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.
* <p/>
* 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<String> processedEntityNames;
private final ArrayList<String> processedEntityNames = new ArrayList<String>();
private InheritanceType currentInheritanceType;
private EntityMode currentHierarchyEntityMode;
private LocalBindingContext currentBindingContext;
private HashMap<String, EntitySource> sourcesByName = new HashMap<String, EntitySource>();
public Binder(MetadataImplementor metadata, List<String> 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<? extends EntityHierarchy> 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<TableSpecification> 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<TableSpecification> 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
*

View File

@ -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() );

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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 );

View File

@ -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;
}
}

View File

@ -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();
}