From 7529dd8e81be0d30c734ffcde8738025c0cc1dea Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 22 Jul 2011 14:27:35 -0500 Subject: [PATCH] HHH-6479 - Split notions of locating and creating an attribute --- .../internal/SessionFactoryImpl.java | 4 +- .../metamodel/binding/EntityBinding.java | 36 +-- .../binding/ManyToOneAttributeBinding.java | 2 +- .../domain/AbstractAttributeContainer.java | 208 ++++++------------ .../metamodel/domain/AttributeContainer.java | 31 ++- .../metamodel/source/binder/Binder.java | 31 ++- .../tuple/entity/EntityMetamodel.java | 2 +- .../binding/SimpleValueBindingTests.java | 2 +- .../entity/EmbeddableBindingTests.java | 2 +- .../criteria/path/SingularAttributePath.java | 2 +- 10 files changed, 138 insertions(+), 182 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 57c1b08a0a..f03391d78f 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -675,7 +675,7 @@ public final class SessionFactoryImpl final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() ); CollectionRegionAccessStrategy accessStrategy = null; if ( accessType != null && settings.isSecondLevelCacheEnabled() ) { - // TODO: is model.getAttribute().getName() the collection's role??? For now, assuming it is + // TODO: is model.locateAttribute().getName() the collection's role??? For now, assuming it is LOG.trace("Building cache for collection data [" + model.getAttribute().getName() + "]"); CollectionRegion collectionRegion = settings.getRegionFactory() @@ -690,7 +690,7 @@ public final class SessionFactoryImpl serviceRegistry .getService( PersisterFactory.class ) .createCollectionPersister( metadata, model, accessStrategy, this ); - // TODO: is model.getAttribute().getName() the collection's role??? For now, assuming it is + // TODO: is model.locateAttribute().getName() the collection's role??? For now, assuming it is collectionPersisters.put( model.getAttribute().getName(), persister.getCollectionMetadata() ); Type indexType = persister.getIndexType(); if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java index c6a3d8d47c..9935a87949 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java @@ -67,21 +67,6 @@ public class EntityBinding { private Set filterDefinitions = new HashSet(); private Set entityReferencingAttributeBindings = new HashSet(); - /** - * Used to instantiate the EntityBinding for an entity that is the root of an inheritance hierarchy - * - * @param inheritanceType The inheritance type for the hierarchy - * @param entityMode The entity mode used in this hierarchy. - */ - public EntityBinding(InheritanceType inheritanceType, EntityMode entityMode) { - this.superEntityBinding = null; - this.hierarchyDetails = new HierarchyDetails( this, inheritanceType, entityMode ); - } - - public EntityBinding(EntityBinding superEntityBinding) { - this.superEntityBinding = superEntityBinding; - this.hierarchyDetails = superEntityBinding.getHierarchyDetails(); - } private MetaAttributeContext metaAttributeContext; @@ -106,6 +91,27 @@ public class EntityBinding { private Set synchronizedTableNames = new HashSet(); + /** + * Used to instantiate the EntityBinding for an entity that is the root of an inheritance hierarchy + * + * @param inheritanceType The inheritance type for the hierarchy + * @param entityMode The entity mode used in this hierarchy. + */ + public EntityBinding(InheritanceType inheritanceType, EntityMode entityMode) { + this.superEntityBinding = null; + this.hierarchyDetails = new HierarchyDetails( this, inheritanceType, entityMode ); + } + + /** + * Used to instantiate the EntityBinding for an entity that is a subclass (sub-entity) in an inheritance hierarchy + * + * @param superEntityBinding The entity binding of this binding's super + */ + public EntityBinding(EntityBinding superEntityBinding) { + this.superEntityBinding = superEntityBinding; + this.hierarchyDetails = superEntityBinding.getHierarchyDetails(); + } + public HierarchyDetails getHierarchyDetails() { return hierarchyDetails; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToOneAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToOneAttributeBinding.java index caf5eec45b..f0a02076a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToOneAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToOneAttributeBinding.java @@ -194,7 +194,7 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im // if ( getCascadeTypes().contains( CascadeType.DELETE_ORPHAN ) ) { // if ( !isLogicalOneToOne ) { // throw new MappingException( -// "many-to-one attribute [" + getAttribute().getName() + "] does not support orphan delete as it is not unique" +// "many-to-one attribute [" + locateAttribute().getName() + "] does not support orphan delete as it is not unique" // ); // } // } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java index fea92b508d..a59571d451 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java @@ -28,7 +28,6 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; -import org.hibernate.HibernateException; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.internal.util.Value; @@ -80,172 +79,97 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, } @Override - public Set getAttributes() { + public Set attributes() { return Collections.unmodifiableSet( attributeSet ); } @Override - public Attribute getAttribute(String name) { + public Attribute locateAttribute(String name) { return attributeMap.get( name ); } @Override - public SingularAttribute locateOrCreateSingularAttribute(String name) { - SingularAttribute attribute = (SingularAttribute) getAttribute( name ); - if ( attribute == null ) { + public SingularAttribute locateSingularAttribute(String name) { + return (SingularAttribute) locateAttribute( name ); + } - attribute = new SingularAttributeImpl( name, this ); - addAttribute( attribute ); - } + @Override + public SingularAttribute createSingularAttribute(String name) { + SingularAttribute attribute = new SingularAttributeImpl( name, this ); + addAttribute( attribute ); return attribute; } @Override - public SingularAttribute locateOrCreateVirtualAttribute(String name) { + public SingularAttribute createVirtualSingularAttribute(String name) { throw new NotYetImplementedException(); } @Override - public SingularAttribute locateOrCreateComponentAttribute(String name) { - SingularAttributeImpl attribute = (SingularAttributeImpl) getAttribute( name ); - if ( attribute == null ) { - ComponentAttributeContainerDelegate component = new ComponentAttributeContainerDelegate(); - attribute = new SingularAttributeImpl( name, component ); - component.singularAttribute = attribute; - addAttribute( attribute ); - } + public SingularAttribute locateComponentAttribute(String name) { + return (SingularAttributeImpl) locateAttribute( name ); + } + + @Override + public SingularAttribute createComponentAttribute(String name, Component component) { + SingularAttributeImpl attribute = new SingularAttributeImpl( name, component ); + addAttribute( attribute ); return attribute; } - private static class ComponentAttributeContainerDelegate implements AttributeContainer { - private SingularAttributeImpl singularAttribute; - - private ComponentAttributeContainerDelegate() { - } - - private Component realComponent() { - if ( singularAttribute.getSingularAttributeType() == null ) { - throw new HibernateException( "Component type was not yet bound" ); - } - if ( ! Component.class.isInstance( singularAttribute.getSingularAttributeType() ) ) { - throw new HibernateException( "Unexpected bound type for component attribute" ); - } - return (Component) singularAttribute.getSingularAttributeType(); - } - - @Override - public Attribute getAttribute(String name) { - return realComponent().getAttribute( name ); - } - - @Override - public Set getAttributes() { - return realComponent().getAttributes(); - } - - @Override - public SingularAttribute locateOrCreateSingularAttribute(String name) { - return realComponent().locateOrCreateSingularAttribute( name ); - } - - @Override - public SingularAttribute locateOrCreateVirtualAttribute(String name) { - return realComponent().locateOrCreateVirtualAttribute( name ); - } - - @Override - public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature) { - return realComponent().locateOrCreatePluralAttribute( name, nature ); - } - - @Override - public PluralAttribute locateOrCreateBag(String name) { - return realComponent().locateOrCreateBag( name ); - } - - @Override - public PluralAttribute locateOrCreateSet(String name) { - return realComponent().locateOrCreateBag( name ); - } - - @Override - public IndexedPluralAttribute locateOrCreateList(String name) { - return realComponent().locateOrCreateList( name ); - } - - @Override - public IndexedPluralAttribute locateOrCreateMap(String name) { - return realComponent().locateOrCreateMap( name ); - } - - @Override - public SingularAttribute locateOrCreateComponentAttribute(String name) { - return realComponent().locateOrCreateComponentAttribute( name ); - } - - @Override - public String getName() { - return realComponent().getName(); - } - - @Override - public String getClassName() { - return realComponent().getClassName(); - } - - @Override - public Class getClassReference() { - return realComponent().getClassReference(); - } - - @Override - public Value> getClassReferenceUnresolved() { - return realComponent().getClassReferenceUnresolved(); - } - - @Override - public boolean isAssociation() { - return realComponent().isAssociation(); - } - - @Override - public boolean isComponent() { - return realComponent().isComponent(); - } + @Override + public PluralAttribute locatePluralAttribute(String name) { + return (PluralAttribute) locateAttribute( name ); } - @Override - public PluralAttribute locateOrCreateBag(String name) { - return locateOrCreatePluralAttribute( name, PluralAttributeNature.BAG ); - } - - @Override - public PluralAttribute locateOrCreateSet(String name) { - return locateOrCreatePluralAttribute( name, PluralAttributeNature.SET ); - } - - @Override - public IndexedPluralAttribute locateOrCreateList(String name) { - return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.LIST ); - } - - @Override - public IndexedPluralAttribute locateOrCreateMap(String name) { - return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.MAP ); - } - - @Override - public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature) { - PluralAttribute attribute = (PluralAttribute) getAttribute( name ); - if ( attribute == null ) { - attribute = nature.isIndexed() - ? new IndexedPluralAttributeImpl( name, nature, this ) - : new PluralAttributeImpl( name, nature, this ); - addAttribute( attribute ); - } + protected PluralAttribute createPluralAttribute(String name, PluralAttributeNature nature) { + PluralAttribute attribute = nature.isIndexed() + ? new IndexedPluralAttributeImpl( name, nature, this ) + : new PluralAttributeImpl( name, nature, this ); + addAttribute( attribute ); return attribute; } + @Override + public PluralAttribute locateBag(String name) { + return locatePluralAttribute( name ); + } + + @Override + public PluralAttribute createBag(String name) { + return createPluralAttribute( name, PluralAttributeNature.BAG ); + } + + @Override + public PluralAttribute locateSet(String name) { + return locatePluralAttribute( name ); + } + + @Override + public PluralAttribute createSet(String name) { + return createPluralAttribute( name, PluralAttributeNature.SET ); + } + + @Override + public IndexedPluralAttribute locateList(String name) { + return (IndexedPluralAttribute) locatePluralAttribute( name ); + } + + @Override + public IndexedPluralAttribute createList(String name) { + return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttributeNature.LIST ); + } + + @Override + public IndexedPluralAttribute locateMap(String name) { + return (IndexedPluralAttribute) locatePluralAttribute( name ); + } + + @Override + public IndexedPluralAttribute createMap(String name) { + return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttributeNature.MAP ); + } + @Override public String toString() { final StringBuilder sb = new StringBuilder(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java index 0a65567eaf..4ead828994 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java @@ -39,23 +39,34 @@ public interface AttributeContainer extends Type { * * @return The attribute matching the given name, or null. */ - public Attribute getAttribute(String name); + public Attribute locateAttribute(String name); /** * Retrieve the attributes contained in this container. * * @return The contained attributes */ - public Set getAttributes(); + public Set attributes(); - public SingularAttribute locateOrCreateSingularAttribute(String name); - public SingularAttribute locateOrCreateVirtualAttribute(String name); + public SingularAttribute locateSingularAttribute(String name); + public SingularAttribute createSingularAttribute(String name); + public SingularAttribute createVirtualSingularAttribute(String name); - public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature); - public PluralAttribute locateOrCreateBag(String name); - public PluralAttribute locateOrCreateSet(String name); - public IndexedPluralAttribute locateOrCreateList(String name); - public IndexedPluralAttribute locateOrCreateMap(String name); + public SingularAttribute locateComponentAttribute(String name); + public SingularAttribute createComponentAttribute(String name, Component component); + + public PluralAttribute locatePluralAttribute(String name); + + public PluralAttribute locateBag(String name); + public PluralAttribute createBag(String name); + + public PluralAttribute locateSet(String name); + public PluralAttribute createSet(String name); + + public IndexedPluralAttribute locateList(String name); + public IndexedPluralAttribute createList(String name); + + public IndexedPluralAttribute locateMap(String name); + public IndexedPluralAttribute createMap(String name); - public SingularAttribute locateOrCreateComponentAttribute(String name); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java index f8d88478b4..8043f3f1f3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/Binder.java @@ -392,7 +392,7 @@ public class Binder { if ( attributeSource.isSingular() ) { final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) attributeSource; if ( singularAttributeSource.getNature() == SingularAttributeNature.COMPONENT ) { - throw new NotYetImplementedException( "Component binding not yet implemented :(" ); + bindComponent( singularAttributeSource, entityBinding ); } else { doBasicSingularAttributeBindingCreation( singularAttributeSource, entityBinding ); @@ -404,13 +404,20 @@ public class Binder { } } + private void bindComponent(SingularAttributeSource singularAttributeSource, EntityBinding entityBinding) { + throw new NotYetImplementedException( "Component binding not yet implemented :(" ); + } + private void bindPersistentCollection(PluralAttributeSource attributeSource, EntityBinding entityBinding) { + final PluralAttribute existingAttribute = entityBinding.getEntity().locatePluralAttribute( attributeSource.getName() ); final AbstractPluralAttributeBinding pluralAttributeBinding; - if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) { - final PluralAttribute pluralAttribute = entityBinding.getEntity() - .locateOrCreateBag( attributeSource.getName() ); + + if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) { + final PluralAttribute attribute = existingAttribute != null + ? existingAttribute + : entityBinding.getEntity().createBag( attributeSource.getName() ); pluralAttributeBinding = entityBinding.makeBagAttributeBinding( - pluralAttribute, + attribute, convert( attributeSource.getPluralAttributeElementNature() ) ); } @@ -434,9 +441,17 @@ public class Binder { private SimpleSingularAttributeBinding doBasicSingularAttributeBindingCreation( SingularAttributeSource attributeSource, EntityBinding entityBinding) { - final SingularAttribute attribute = attributeSource.isVirtualAttribute() - ? entityBinding.getEntity().locateOrCreateVirtualAttribute( attributeSource.getName() ) - : entityBinding.getEntity().locateOrCreateSingularAttribute( attributeSource.getName() ); + final SingularAttribute existingAttribute = entityBinding.getEntity().locateSingularAttribute( attributeSource.getName() ); + final SingularAttribute attribute; + if ( existingAttribute != null ) { + attribute = existingAttribute; + } + else if ( attributeSource.isVirtualAttribute() ) { + attribute = entityBinding.getEntity().createVirtualSingularAttribute( attributeSource.getName() ); + } + else { + attribute = entityBinding.getEntity().createSingularAttribute( attributeSource.getName() ); + } final SimpleSingularAttributeBinding attributeBinding; if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 7a6073b6ad..289ae23479 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -702,7 +702,7 @@ public class EntityMetamodel implements Serializable { ( ( SingularAttribute ) attribute ).getSingularAttributeType().isComponent() ) { org.hibernate.metamodel.domain.Component component = ( org.hibernate.metamodel.domain.Component ) ( ( SingularAttribute ) attribute ).getSingularAttributeType(); - for ( Attribute subAttribute : component.getAttributes() ) { + for ( Attribute subAttribute : component.attributes() ) { propertyIndexes.put( attribute.getName() + '.' + subAttribute.getName(), i diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java index 2996f015d8..3eddd724f8 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java @@ -60,7 +60,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase { entityBinding.setEntity( entity ); entityBinding.setBaseTable( table ); - SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" ); + SingularAttribute idAttribute = entity.createSingularAttribute( "id" ); SimpleSingularAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute ); attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" ); assertSame( idAttribute, attributeBinding.getAttribute() ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java index bee94dbdcb..0f3e390eeb 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java @@ -53,7 +53,7 @@ public class EmbeddableBindingTests extends BaseAnnotationBindingTestCase { assertNotNull( binding.getAttributeBinding( "city" ) ); assertNotNull( binding.getAttributeBinding( "postCode" ) ); - SingularAttribute attribute = (SingularAttribute) binding.getEntity().getAttribute( "address" ); + SingularAttribute attribute = (SingularAttribute) binding.getEntity().locateAttribute( "address" ); assertTrue( "Wrong container type. Should be a component", attribute.getSingularAttributeType() instanceof Component diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/SingularAttributePath.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/SingularAttributePath.java index e76864184b..66211f28a7 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/SingularAttributePath.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/SingularAttributePath.java @@ -93,7 +93,7 @@ public class SingularAttributePath extends AbstractPathImpl implements Ser @Override protected Attribute locateAttributeInternal(String attributeName) { final Attribute attribute = managedType.getAttribute( attributeName ); - // ManagedType.getAttribute should throw exception rather than return + // ManagedType.locateAttribute should throw exception rather than return // null, but just to be safe... if ( attribute == null ) { throw new IllegalArgumentException( "Could not resolve attribute named " + attributeName );