From e540089783133ad692355fb7ac36b368fea73b4b Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 25 Jul 2011 14:16:48 -0500 Subject: [PATCH] HHH-6480 - Develop component binding for new metamodel --- .../internal/CacheDataDescriptionImpl.java | 4 +- .../binding/AbstractAttributeBinding.java | 22 +- .../AbstractAttributeBindingContainer.java | 114 +++++++++ .../AbstractPluralAttributeBinding.java | 4 +- .../AbstractSingularAttributeBinding.java | 8 +- .../metamodel/binding/AttributeBinding.java | 2 +- .../binding/AttributeBindingContainer.java | 61 +++++ .../metamodel/binding/BagBinding.java | 4 +- .../binding/ComponentAttributeBinding.java | 167 +++++++++++++ .../metamodel/binding/EntityBinding.java | 92 ++------ .../binding/ManyToOneAttributeBinding.java | 15 +- .../SimpleSingularAttributeBinding.java | 6 +- .../domain/AbstractAttributeContainer.java | 3 +- .../annotations/entity/EntitySourceImpl.java | 11 +- .../binder/AttributeSourceContainer.java | 20 +- .../metamodel/source/binder/Binder.java | 81 ++++--- .../binder/ComponentAttributeSource.java | 36 +++ .../metamodel/source/binder/EntitySource.java | 2 +- .../source/hbm/AbstractEntitySourceImpl.java | 21 +- .../hbm/ComponentAttributeSourceImpl.java | 220 ++++++++++++++++++ .../source/hbm/RootEntitySourceImpl.java | 5 + .../source/hbm/SubclassEntitySourceImpl.java | 8 + .../source/internal/AssociationResolver.java | 2 +- .../internal/AttributeTypeResolver.java | 2 +- .../source/internal/MetadataImpl.java | 4 +- .../entity/AbstractEntityPersister.java | 9 +- .../entity/SingleTableEntityPersister.java | 8 +- .../org/hibernate/tuple/PropertyFactory.java | 6 +- .../tuple/entity/PojoEntityTuplizer.java | 8 +- .../binding/AbstractBasicBindingTests.java | 55 +++-- .../binding/BasicAnnotationBindingTests.java | 18 +- .../binding/BasicHbmBindingTests.java | 15 +- .../SimpleEntityWithSimpleComponent.hbm.xml | 19 ++ .../SimpleEntityWithSimpleComponent.java | 92 ++++++++ .../annotations/entity/AccessBindingTest.java | 12 +- .../entity/MappedSuperclassTest.java | 5 +- .../entity/QuotedIdentifierTest.java | 2 +- .../annotations/entity/TableNameTest.java | 12 +- .../entity/UniqueConstraintBindingTest.java | 2 +- 39 files changed, 968 insertions(+), 209 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBindingContainer.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBindingContainer.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binding/ComponentAttributeBinding.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/ComponentAttributeSource.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/ComponentAttributeSourceImpl.java create mode 100644 hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml create mode 100644 hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.java diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java index 34c988e394..ecfe6932f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java @@ -87,8 +87,8 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { public static CacheDataDescriptionImpl decode(AbstractPluralAttributeBinding model) { return new CacheDataDescriptionImpl( model.isMutable(), - model.getEntityBinding().isVersioned(), - getVersionComparator( model.getEntityBinding() ) + model.getContainer().seekEntityBinding().isVersioned(), + getVersionComparator( model.getContainer().seekEntityBinding() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java index 4363aae9bc..4ae33f270a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java @@ -36,7 +36,7 @@ import org.hibernate.metamodel.source.MetaAttributeContext; * @author Steve Ebersole */ public abstract class AbstractAttributeBinding implements AttributeBinding { - private final EntityBinding entityBinding; + private final AttributeBindingContainer container; private final Attribute attribute; private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); @@ -50,14 +50,14 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { private MetaAttributeContext metaAttributeContext; - protected AbstractAttributeBinding(EntityBinding entityBinding, Attribute attribute) { - this.entityBinding = entityBinding; + protected AbstractAttributeBinding(AttributeBindingContainer container, Attribute attribute) { + this.container = container; this.attribute = attribute; } @Override - public EntityBinding getEntityBinding() { - return entityBinding; + public AttributeBindingContainer getContainer() { + return container; } @Override @@ -93,18 +93,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { this.includedInOptimisticLocking = includedInOptimisticLocking; } - protected boolean forceNonNullable() { - return false; - } - - protected boolean forceUnique() { - return false; - } - - protected final boolean isPrimaryKey() { - return this == getEntityBinding().getHierarchyDetails().getEntityIdentifier().getValueBinding(); - } - @Override public MetaAttributeContext getMetaAttributeContext() { return metaAttributeContext; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBindingContainer.java new file mode 100644 index 0000000000..22571f71a1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBindingContainer.java @@ -0,0 +1,114 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binding; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.metamodel.domain.PluralAttribute; +import org.hibernate.metamodel.domain.SingularAttribute; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractAttributeBindingContainer implements AttributeBindingContainer { + private Map attributeBindingMap = new HashMap(); + + protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) { + attributeBindingMap.put( name, attributeBinding ); + } + + @Override + public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) { + return makeSimpleAttributeBinding( attribute, false, false ); + } + + private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) { + final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( + this, + attribute, + forceNonNullable, + forceUnique + ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) { + final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) { + final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) { + final BagBinding binding = new BagBinding( this, attribute, nature ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public AttributeBinding locateAttributeBinding(String name) { + return attributeBindingMap.get( name ); + } + + @Override + public Iterable attributeBindings() { + return attributeBindingMap.values(); + } + + /** + * Gets the number of attribute bindings defined on this class, including the + * identifier attribute binding and attribute bindings defined + * as part of a join. + * + * @return The number of attribute bindings + */ + public int getAttributeBindingClosureSpan() { + // TODO: fix this after HHH-6337 is fixed; for now just return size of attributeBindingMap + // if this is not a root, then need to include the superclass attribute bindings + return attributeBindingMap.size(); + } + + /** + * Gets the attribute bindings defined on this class, including the + * identifier attribute binding and attribute bindings defined + * as part of a join. + * + * @return The attribute bindings. + */ + public Iterable getAttributeBindingClosure() { + // TODO: fix this after HHH-6337 is fixed. for now, just return attributeBindings + // if this is not a root, then need to include the superclass attribute bindings + return attributeBindings(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java index ca141eaad1..ee5466a53f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java @@ -77,10 +77,10 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi private String loaderName; protected AbstractPluralAttributeBinding( - EntityBinding entityBinding, + AttributeBindingContainer container, PluralAttribute attribute, CollectionElementNature collectionElementNature) { - super( entityBinding, attribute ); + super( container, attribute ); this.collectionElement = interpretNature( collectionElementNature ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractSingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractSingularAttributeBinding.java index 29ef6b0cfd..ef7fb1fded 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractSingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractSingularAttributeBinding.java @@ -45,8 +45,8 @@ public abstract class AbstractSingularAttributeBinding private boolean hasDerivedValue; private boolean isNullable = true; - protected AbstractSingularAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) { - super( entityBinding, attribute ); + protected AbstractSingularAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) { + super( container, attribute ); } @Override @@ -79,7 +79,7 @@ public abstract class AbstractSingularAttributeBinding } private String getRole() { - return getEntityBinding().getEntity().getName() + '.' + getAttribute().getName(); + return getContainer().getPathBase() + '.' + getAttribute().getName(); } @Override @@ -88,7 +88,7 @@ public abstract class AbstractSingularAttributeBinding return simpleValueBindings.size(); } - private void checkValueBinding() { + protected void checkValueBinding() { if ( value == null ) { throw new AssertionFailure( "No values yet bound!" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java index 8903e32daf..5d317cc01e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java @@ -39,7 +39,7 @@ public interface AttributeBinding { * * @return The entity binding. */ - public EntityBinding getEntityBinding(); + public AttributeBindingContainer getContainer(); /** * Obtain the attribute bound. diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBindingContainer.java new file mode 100644 index 0000000000..0465a05241 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBindingContainer.java @@ -0,0 +1,61 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binding; + +import org.hibernate.metamodel.domain.AttributeContainer; +import org.hibernate.metamodel.domain.PluralAttribute; +import org.hibernate.metamodel.domain.SingularAttribute; +import org.hibernate.metamodel.relational.TableSpecification; +import org.hibernate.metamodel.source.MetaAttributeContext; + +/** + * @author Steve Ebersole + */ +public interface AttributeBindingContainer { + public String getPathBase(); + + public AttributeContainer getAttributeContainer(); + + public Iterable attributeBindings(); + + public AttributeBinding locateAttributeBinding(String name); + + public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute); + + public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute); + + public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute); + + public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature); + + public EntityBinding seekEntityBinding(); + + public TableSpecification getPrimaryTable(); + + public TableSpecification locateTable(String containingTableName); + + public Class getClassReference(); + + public MetaAttributeContext getMetaAttributeContext(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java index 633339a80f..099fb5110c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java @@ -31,7 +31,7 @@ import org.hibernate.metamodel.domain.PluralAttribute; * @author Steve Ebersole */ public class BagBinding extends AbstractPluralAttributeBinding { - protected BagBinding(EntityBinding entityBinding, PluralAttribute attribute, CollectionElementNature nature) { - super( entityBinding, attribute, nature ); + protected BagBinding(AttributeBindingContainer container, PluralAttribute attribute, CollectionElementNature nature) { + super( container, attribute, nature ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ComponentAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ComponentAttributeBinding.java new file mode 100644 index 0000000000..43de669f6e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ComponentAttributeBinding.java @@ -0,0 +1,167 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binding; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.domain.AttributeContainer; +import org.hibernate.metamodel.domain.Component; +import org.hibernate.metamodel.domain.PluralAttribute; +import org.hibernate.metamodel.domain.SingularAttribute; +import org.hibernate.metamodel.relational.TableSpecification; +import org.hibernate.metamodel.source.MetaAttributeContext; + +/** + * @author Steve Ebersole + */ +public class ComponentAttributeBinding extends AbstractSingularAttributeBinding implements AttributeBindingContainer { + private final String path; + private Map attributeBindingMap = new HashMap(); + + private SingularAttribute parentReference; + + private MetaAttributeContext metaAttributeContext; + + public ComponentAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) { + super( container, attribute ); + this.path = container.getPathBase() + '.' + attribute.getName(); + } + + @Override + public EntityBinding seekEntityBinding() { + return getContainer().seekEntityBinding(); + } + + @Override + public String getPathBase() { + return path; + } + + @Override + public AttributeContainer getAttributeContainer() { + return getComponent(); + } + + public Component getComponent() { + return (Component) getAttribute().getSingularAttributeType(); + } + + @Override + public boolean isAssociation() { + return false; + } + + @Override + public MetaAttributeContext getMetaAttributeContext() { + return metaAttributeContext; + } + + public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) { + this.metaAttributeContext = metaAttributeContext; + } + + @Override + public TableSpecification getPrimaryTable() { + return getContainer().getPrimaryTable(); + } + + @Override + public TableSpecification locateTable(String containingTableName) { + return getContainer().locateTable( containingTableName ); + } + + @Override + public AttributeBinding locateAttributeBinding(String name) { + return attributeBindingMap.get( name ); + } + + @Override + public Iterable attributeBindings() { + return attributeBindingMap.values(); + } + + @Override + protected void checkValueBinding() { + // do nothing here... + } + + @Override + public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) { + final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( + this, + attribute, + isNullable(), + isAlternateUniqueKey() // todo : is this accurate? + ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) { + // todo : hook this into the EntityBinding notion of "entity referencing attribute bindings" + attributeBindingMap.put( name, attributeBinding ); + } + + @Override + public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) { + final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) { + final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) { + final BagBinding binding = new BagBinding( this, attribute, nature ); + registerAttributeBinding( attribute.getName(), binding ); + return binding; + } + + @Override + public Class getClassReference() { + return getComponent().getClassReference(); + } + + public SingularAttribute getParentReference() { + return parentReference; + } + + public void setParentReference(SingularAttribute parentReference) { + this.parentReference = parentReference; + } + + @Override + public PropertyGeneration getGeneration() { + // todo : not sure the correct thing to return here since it essentially relies on the simple sub-attributes. + return null; + } +} 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 1794ff855c..51cb648cdb 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 @@ -32,9 +32,8 @@ import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.internal.util.Value; +import org.hibernate.metamodel.domain.AttributeContainer; import org.hibernate.metamodel.domain.Entity; -import org.hibernate.metamodel.domain.PluralAttribute; -import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.metamodel.source.MetaAttributeContext; import org.hibernate.persister.entity.EntityPersister; @@ -47,7 +46,7 @@ import org.hibernate.tuple.entity.EntityTuplizer; * @author Hardy Ferentschik * @author Gail Badner */ -public class EntityBinding { +public class EntityBinding extends AbstractAttributeBindingContainer { private final EntityBinding superEntityBinding; private final HierarchyDetails hierarchyDetails; @@ -64,12 +63,9 @@ public class EntityBinding { private String discriminatorMatchValue; - private Map attributeBindingMap = new HashMap(); - private Set filterDefinitions = new HashSet(); private Set entityReferencingAttributeBindings = new HashSet(); - private MetaAttributeContext metaAttributeContext; private boolean lazy; @@ -135,7 +131,8 @@ public class EntityBinding { this.entity = entity; } - public TableSpecification getBaseTable() { + @Override + public TableSpecification getPrimaryTable() { return baseTable; } @@ -143,7 +140,7 @@ public class EntityBinding { this.baseTable = baseTable; } - public TableSpecification getTable(String tableName) { + public TableSpecification locateTable(String tableName) { if ( tableName == null ) { return baseTable; } @@ -171,40 +168,6 @@ public class EntityBinding { this.discriminatorMatchValue = discriminatorMatchValue; } - public Iterable getAttributeBindings() { - return attributeBindingMap.values(); - } - - public AttributeBinding getAttributeBinding(String name) { - return attributeBindingMap.get( name ); - } - - /** - * Gets the number of attribute bindings defined on this class, including the - * identifier attribute binding and attribute bindings defined - * as part of a join. - * - * @return The number of attribute bindings - */ - public int getAttributeBindingClosureSpan() { - // TODO: fix this after HHH-6337 is fixed; for now just return size of attributeBindingMap - // if this is not a root, then need to include the superclass attribute bindings - return attributeBindingMap.size(); - } - - /** - * Gets the attribute bindings defined on this class, including the - * identifier attribute binding and attribute bindings defined - * as part of a join. - * - * @return The attribute bindings. - */ - public Iterable getAttributeBindingClosure() { - // TODO: fix this after HHH-6337 is fixed. for now, just return attributeBindings - // if this is not a root, then need to include the superclass attribute bindings - return getAttributeBindings(); - } - public Iterable getFilterDefinitions() { return filterDefinitions; } @@ -217,42 +180,35 @@ public class EntityBinding { return entityReferencingAttributeBindings; } - public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) { - return makeSimpleAttributeBinding( attribute, false, false ); + @Override + public EntityBinding seekEntityBinding() { + return this; } - private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) { - final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( - this, - attribute, - forceNonNullable, - forceUnique - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; + @Override + public String getPathBase() { + return getEntity().getName(); } - public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) { - final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; + @Override + public Class getClassReference() { + return getEntity().getClassReference(); } - public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) { - final BagBinding binding = new BagBinding( this, attribute, nature ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; + @Override + public AttributeContainer getAttributeContainer() { + return getEntity(); } - private void registerAttributeBinding(String name, SingularAssociationAttributeBinding attributeBinding) { - entityReferencingAttributeBindings.add( attributeBinding ); - registerAttributeBinding( name, (AttributeBinding) attributeBinding ); - } - - private void registerAttributeBinding(String name, AttributeBinding attributeBinding) { - attributeBindingMap.put( name, attributeBinding ); + @Override + protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) { + if ( SingularAssociationAttributeBinding.class.isInstance( attributeBinding ) ) { + entityReferencingAttributeBindings.add( (SingularAssociationAttributeBinding) attributeBinding ); + } + super.registerAttributeBinding( name, attributeBinding ); } + @Override public MetaAttributeContext getMetaAttributeContext() { return metaAttributeContext; } 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 f0a02076a9..84f3e86241 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 @@ -26,6 +26,7 @@ package org.hibernate.metamodel.binding; import java.util.ArrayList; import java.util.List; +import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.metamodel.domain.SingularAttribute; @@ -47,8 +48,8 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im private CascadeStyle cascadeStyle; private FetchMode fetchMode; - ManyToOneAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) { - super( entityBinding, attribute, false, false ); + ManyToOneAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) { + super( container, attribute, false, false ); } @Override @@ -124,10 +125,14 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im @Override public final void resolveReference(AttributeBinding referencedAttributeBinding) { - if ( !referencedEntityName.equals( referencedAttributeBinding.getEntityBinding().getEntity().getName() ) ) { + if ( ! EntityBinding.class.isInstance( referencedAttributeBinding.getContainer() ) ) { + throw new AssertionFailure( "Illegal attempt to resolve many-to-one reference based on non-entity attribute" ); + } + final EntityBinding entityBinding = (EntityBinding) referencedAttributeBinding.getContainer(); + if ( !referencedEntityName.equals( entityBinding.getEntity().getName() ) ) { throw new IllegalStateException( "attempt to set EntityBinding with name: [" + - referencedAttributeBinding.getEntityBinding().getEntity().getName() + + entityBinding.getEntity().getName() + "; entity name should be: " + referencedEntityName ); } @@ -154,7 +159,7 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im @Override public final EntityBinding getReferencedEntityBinding() { - return referencedAttributeBinding.getEntityBinding(); + return (EntityBinding) referencedAttributeBinding.getContainer(); } // private void buildForeignKey() { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleSingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleSingularAttributeBinding.java index 554a696170..595625248b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleSingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleSingularAttributeBinding.java @@ -56,11 +56,11 @@ public class SimpleSingularAttributeBinding private MetaAttributeContext metaAttributeContext; SimpleSingularAttributeBinding( - EntityBinding entityBinding, + AttributeBindingContainer container, SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) { - super( entityBinding, attribute ); + super( container, attribute ); this.forceNonNullable = forceNonNullable; this.forceUnique = forceUnique; } @@ -144,7 +144,7 @@ public class SimpleSingularAttributeBinding // TODO: not sure how this works for collection IDs... //pass the entity-name, if not a collection-id //if ( rootClass!=null) { - params.setProperty( IdentifierGenerator.ENTITY_NAME, getEntityBinding().getEntity().getName() ); + params.setProperty( IdentifierGenerator.ENTITY_NAME, getContainer().seekEntityBinding().getEntity().getName() ); //} //init the table here instead of earlier, so that we can get a quoted table name 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 a59571d451..51cda724c1 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 @@ -112,7 +112,8 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, @Override public SingularAttribute createComponentAttribute(String name, Component component) { - SingularAttributeImpl attribute = new SingularAttributeImpl( name, component ); + SingularAttributeImpl attribute = new SingularAttributeImpl( name, this ); + attribute.resolveType( component ); addAttribute( attribute ); return attribute; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntitySourceImpl.java index e806f2c335..d2fc925d49 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntitySourceImpl.java @@ -58,11 +58,13 @@ public class EntitySourceImpl implements EntitySource { private final EntityClass entityClass; private final Set subclassEntitySources; private final Origin origin; + private final LocalBindingContextImpl localBindingContext; public EntitySourceImpl(EntityClass entityClass) { this.entityClass = entityClass; this.subclassEntitySources = new HashSet(); this.origin = new Origin( SourceType.ANNOTATION, entityClass.getName() ); + this.localBindingContext = new LocalBindingContextImpl( entityClass.getContext() ); } public EntityClass getEntityClass() { @@ -75,8 +77,8 @@ public class EntitySourceImpl implements EntitySource { } @Override - public LocalBindingContext getBindingContext() { - return new LocalBindingContextImpl( entityClass.getContext() ); + public LocalBindingContext getLocalBindingContext() { + return localBindingContext; } @Override @@ -174,6 +176,11 @@ public class EntitySourceImpl implements EntitySource { return Collections.emptySet(); } + @Override + public String getPath() { + return entityClass.getName(); + } + @Override public Iterable attributeSources() { List attributeList = new ArrayList(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/AttributeSourceContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/AttributeSourceContainer.java index 5371c4d29c..d4d088bbe3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/AttributeSourceContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/AttributeSourceContainer.java @@ -23,6 +23,8 @@ */ package org.hibernate.metamodel.source.binder; +import org.hibernate.metamodel.source.LocalBindingContext; + /** * Contract for a container of {@link AttributeSource} references. Both entities and components contain * attributes. @@ -31,9 +33,23 @@ package org.hibernate.metamodel.source.binder; */ public interface AttributeSourceContainer { /** - Obtain this container's attribute sources. + * Obtain the path used to uniquely identify this container. * - * @return TYhe attribute sources. + * @return The unique identifier path + */ + public String getPath(); + + /** + * Obtain this container's attribute sources. + * + * @return The attribute sources. */ public Iterable attributeSources(); + + /** + * Obtain the local binding context associated with this container. + * + * @return The local binding context + */ + public LocalBindingContext getLocalBindingContext(); } 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 a5be5ae056..84850bfd96 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 @@ -34,10 +34,11 @@ import org.hibernate.EntityMode; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.beans.BeanInfoHelper; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding; +import org.hibernate.metamodel.binding.AttributeBindingContainer; import org.hibernate.metamodel.binding.CollectionElementNature; +import org.hibernate.metamodel.binding.ComponentAttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityDiscriminator; import org.hibernate.metamodel.binding.InheritanceType; @@ -48,6 +49,7 @@ import org.hibernate.metamodel.binding.SimpleValueBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.binding.TypeDef; import org.hibernate.metamodel.domain.Attribute; +import org.hibernate.metamodel.domain.Component; import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.PluralAttribute; import org.hibernate.metamodel.domain.SingularAttribute; @@ -116,7 +118,7 @@ public class Binder { return metadata.getEntityBinding( entitySource.getEntityName() ); } - currentBindingContext = entitySource.getBindingContext(); + currentBindingContext = entitySource.getLocalBindingContext(); try { final EntityBinding entityBinding = doCreateEntityBinding( entitySource, superEntityBinding ); @@ -266,7 +268,7 @@ public class Binder { private EntityBinding makeDiscriminatedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) { final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding ); - entityBinding.setBaseTable( superEntityBinding.getBaseTable() ); + entityBinding.setBaseTable( superEntityBinding.getPrimaryTable() ); bindDiscriminatorValue( entitySource, entityBinding ); @@ -332,12 +334,12 @@ public class Binder { // this should never ever happen.. throw new AssertionFailure( "Simple-id was not a column." ); } - entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) ); + entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) ); } else { for ( SimpleValue subValue : ( (Tuple) relationalValue ).values() ) { if ( Column.class.isInstance( subValue ) ) { - entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) ); + entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) ); } } } @@ -388,7 +390,7 @@ public class Binder { entityBinding.setDiscriminatorMatchValue( discriminatorValue ); } - private void bindAttributes(AttributeSourceContainer attributeSourceContainer, EntityBinding entityBinding) { + private void bindAttributes(AttributeSourceContainer attributeSourceContainer, AttributeBindingContainer attributeBindingContainer) { // todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes. // todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc // for now, simply assume all columns come from the base table.... @@ -397,32 +399,54 @@ public class Binder { if ( attributeSource.isSingular() ) { final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) attributeSource; if ( singularAttributeSource.getNature() == SingularAttributeNature.COMPONENT ) { - bindComponent( singularAttributeSource, entityBinding ); + bindComponent( (ComponentAttributeSource) singularAttributeSource, attributeBindingContainer ); } else { - doBasicSingularAttributeBindingCreation( singularAttributeSource, entityBinding ); + doBasicSingularAttributeBindingCreation( singularAttributeSource, attributeBindingContainer ); } } else { - bindPersistentCollection( (PluralAttributeSource) attributeSource, entityBinding ); + bindPersistentCollection( (PluralAttributeSource) attributeSource, attributeBindingContainer ); } } } - private void bindComponent(SingularAttributeSource singularAttributeSource, EntityBinding entityBinding) { - throw new NotYetImplementedException( "Component binding not yet implemented :(" ); + private void bindComponent(ComponentAttributeSource attributeSource, AttributeBindingContainer container) { + final String attributeName = attributeSource.getName(); + SingularAttribute attribute = container.getAttributeContainer().locateComponentAttribute( attributeName ); + if ( attribute == null ) { + final Component component = new Component( + attributeSource.getPath(), + attributeSource.getClassName(), + attributeSource.getClassReference(), + null // component inheritance not YET supported + ); + attribute = container.getAttributeContainer().createComponentAttribute( attributeName, component ); + } + ComponentAttributeBinding componentAttributeBinding = container.makeComponentAttributeBinding( attribute ); + + if ( StringHelper.isNotEmpty( attributeSource.getParentReferenceAttributeName() ) ) { + final SingularAttribute parentReferenceAttribute = + componentAttributeBinding.getComponent().createSingularAttribute( attributeSource.getParentReferenceAttributeName() ); + componentAttributeBinding.setParentReference( parentReferenceAttribute ); + } + + componentAttributeBinding.setMetaAttributeContext( + buildMetaAttributeContext( attributeSource.metaAttributes(), container.getMetaAttributeContext() ) + ); + + bindAttributes( attributeSource, componentAttributeBinding ); } - private void bindPersistentCollection(PluralAttributeSource attributeSource, EntityBinding entityBinding) { - final PluralAttribute existingAttribute = entityBinding.getEntity() - .locatePluralAttribute( attributeSource.getName() ); + private void bindPersistentCollection(PluralAttributeSource attributeSource, AttributeBindingContainer attributeBindingContainer) { + final PluralAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locatePluralAttribute( attributeSource.getName() ); final AbstractPluralAttributeBinding pluralAttributeBinding; if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) { final PluralAttribute attribute = existingAttribute != null ? existingAttribute - : entityBinding.getEntity().createBag( attributeSource.getName() ); - pluralAttributeBinding = entityBinding.makeBagAttributeBinding( + : attributeBindingContainer.getAttributeContainer().createBag( attributeSource.getName() ); + pluralAttributeBinding = attributeBindingContainer.makeBagAttributeBinding( attribute, convert( attributeSource.getPluralAttributeElementNature() ) ); @@ -446,27 +470,26 @@ public class Binder { private SimpleSingularAttributeBinding doBasicSingularAttributeBindingCreation( SingularAttributeSource attributeSource, - EntityBinding entityBinding) { - final SingularAttribute existingAttribute = entityBinding.getEntity() - .locateSingularAttribute( attributeSource.getName() ); + AttributeBindingContainer attributeBindingContainer) { + final SingularAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() ); final SingularAttribute attribute; if ( existingAttribute != null ) { attribute = existingAttribute; } else if ( attributeSource.isVirtualAttribute() ) { - attribute = entityBinding.getEntity().createVirtualSingularAttribute( attributeSource.getName() ); + attribute = attributeBindingContainer.getAttributeContainer().createVirtualSingularAttribute( attributeSource.getName() ); } else { - attribute = entityBinding.getEntity().createSingularAttribute( attributeSource.getName() ); + attribute = attributeBindingContainer.getAttributeContainer().createSingularAttribute( attributeSource.getName() ); } final SimpleSingularAttributeBinding attributeBinding; if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) { - attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute ); + attributeBinding = attributeBindingContainer.makeSimpleAttributeBinding( attribute ); resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); } else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) { - attributeBinding = entityBinding.makeManyToOneAttributeBinding( attribute ); + attributeBinding = attributeBindingContainer.makeManyToOneAttributeBinding( attribute ); resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); resolveToOneInformation( (ToOneAttributeSource) attributeSource, @@ -492,7 +515,7 @@ public class Binder { bindRelationalValues( attributeSource, attributeBinding ); attributeBinding.setMetaAttributeContext( - buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() ) + buildMetaAttributeContext( attributeSource.metaAttributes(), attributeBindingContainer.getMetaAttributeContext() ) ); return attributeBinding; @@ -660,7 +683,7 @@ public class Binder { private void bindTableUniqueConstraints(EntitySource entitySource, EntityBinding entityBinding) { for ( ConstraintSource constraintSource : entitySource.getConstraints() ) { if ( constraintSource instanceof UniqueConstraintSource ) { - TableSpecification table = entityBinding.getTable( constraintSource.getTableName() ); + TableSpecification table = entityBinding.locateTable( constraintSource.getTableName() ); if ( table == null ) { // throw exception !? } @@ -685,8 +708,8 @@ public class Binder { if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) { for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) { - final TableSpecification table = attributeBinding.getEntityBinding() - .getTable( valueSource.getContainingTableName() ); + final TableSpecification table = attributeBinding.getContainer() + .locateTable( valueSource.getContainingTableName() ); if ( ColumnSource.class.isInstance( valueSource ) ) { final ColumnSource columnSource = ColumnSource.class.cast( valueSource ); @@ -714,7 +737,7 @@ public class Binder { .propertyToColumnName( attributeBinding.getAttribute().getName() ); valueBindings.add( new SimpleValueBinding( - attributeBinding.getEntityBinding().getBaseTable().locateOrCreateColumn( name ) + attributeBinding.getContainer().getPrimaryTable().locateOrCreateColumn( name ) ) ); } @@ -724,7 +747,7 @@ public class Binder { private SimpleValue makeSimpleValue( EntityBinding entityBinding, RelationalValueSource valueSource) { - final TableSpecification table = entityBinding.getTable( valueSource.getContainingTableName() ); + final TableSpecification table = entityBinding.locateTable( valueSource.getContainingTableName() ); if ( ColumnSource.class.isInstance( valueSource ) ) { return makeColumn( (ColumnSource) valueSource, table ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/ComponentAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/ComponentAttributeSource.java new file mode 100644 index 0000000000..3448bdccaf --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/ComponentAttributeSource.java @@ -0,0 +1,36 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.source.binder; + +import org.hibernate.internal.util.Value; + +/** + * @author Steve Ebersole + */ +public interface ComponentAttributeSource extends SingularAttributeSource, AttributeSourceContainer { + public String getClassName(); + public Value> getClassReference(); + + public String getParentReferenceAttributeName(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/EntitySource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/EntitySource.java index 7c0e529231..238a9fe291 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/EntitySource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/binder/EntitySource.java @@ -47,7 +47,7 @@ public interface EntitySource extends SubclassEntityContainer, AttributeSourceCo * * @return The local binding context */ - public LocalBindingContext getBindingContext(); + public LocalBindingContext getLocalBindingContext(); /** * Obtain the entity name diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntitySourceImpl.java index 08df3d96d6..578ccfe97e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntitySourceImpl.java @@ -41,6 +41,7 @@ import org.hibernate.metamodel.source.binder.SubclassEntitySource; import org.hibernate.metamodel.source.binder.TableSource; import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLComponentElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement; @@ -78,7 +79,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource { } @Override - public LocalBindingContext getBindingContext() { + public LocalBindingContext getLocalBindingContext() { return sourceMappingDocument.getMappingLocalBindingContext(); } @@ -91,7 +92,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource { @Override public String getClassName() { - return getBindingContext().qualifyClassName( entityElement.getName() ); + return getLocalBindingContext().qualifyClassName( entityElement.getName() ); } @Override @@ -154,7 +155,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource { @Override public String getCustomPersisterClassName() { - return getBindingContext().qualifyClassName( entityElement.getPersister() ); + return getLocalBindingContext().qualifyClassName( entityElement.getPersister() ); } @Override @@ -191,6 +192,11 @@ public abstract class AbstractEntitySourceImpl implements EntitySource { return Helper.buildMetaAttributeSources( entityElement.getMeta() ); } + @Override + public String getPath() { + return sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement ); + } + @Override public Iterable attributeSources() { List attributeSources = new ArrayList(); @@ -203,6 +209,15 @@ public abstract class AbstractEntitySourceImpl implements EntitySource { ) ); } + else if ( XMLComponentElement.class.isInstance( attributeElement ) ) { + attributeSources.add( + new ComponentAttributeSourceImpl( + (XMLComponentElement) attributeElement, + this, + sourceMappingDocument.getMappingLocalBindingContext() + ) + ); + } else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) { attributeSources.add( new ManyToOneAttributeSourceImpl( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/ComponentAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/ComponentAttributeSourceImpl.java new file mode 100644 index 0000000000..70f6726e3b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/ComponentAttributeSourceImpl.java @@ -0,0 +1,220 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.source.hbm; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.internal.util.Value; +import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.source.LocalBindingContext; +import org.hibernate.metamodel.source.binder.AttributeSource; +import org.hibernate.metamodel.source.binder.AttributeSourceContainer; +import org.hibernate.metamodel.source.binder.ComponentAttributeSource; +import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource; +import org.hibernate.metamodel.source.binder.MetaAttributeSource; +import org.hibernate.metamodel.source.binder.RelationalValueSource; +import org.hibernate.metamodel.source.binder.SingularAttributeNature; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLComponentElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToOneElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement; + +/** + * @author Steve Ebersole + */ +public class ComponentAttributeSourceImpl implements ComponentAttributeSource { + private final XMLComponentElement componentElement; + private final AttributeSourceContainer parentContainer; + + private final Value> componentClassReference; + private final String path; + + public ComponentAttributeSourceImpl( + XMLComponentElement componentElement, + AttributeSourceContainer parentContainer, + LocalBindingContext bindingContext) { + this.componentElement = componentElement; + this.parentContainer = parentContainer; + + this.componentClassReference = bindingContext.makeClassReference( componentElement.getClazz() ); + this.path = parentContainer.getPath() + '.' + componentElement.getName(); + } + + @Override + public String getClassName() { + return componentElement.getClazz(); + } + + @Override + public Value> getClassReference() { + return componentClassReference; + } + + @Override + public String getPath() { + return path; + } + + @Override + public LocalBindingContext getLocalBindingContext() { + return parentContainer.getLocalBindingContext(); + } + + @Override + public String getParentReferenceAttributeName() { + return componentElement.getParent() == null ? null : componentElement.getParent().getName(); + } + + @Override + public Iterable attributeSources() { + List attributeSources = new ArrayList(); + for ( Object attributeElement : componentElement.getPropertyOrManyToOneOrOneToOne() ) { + if ( XMLPropertyElement.class.isInstance( attributeElement ) ) { + attributeSources.add( + new PropertyAttributeSourceImpl( + XMLPropertyElement.class.cast( attributeElement ), + getLocalBindingContext() + ) + ); + } + else if ( XMLComponentElement.class.isInstance( attributeElement ) ) { + attributeSources.add( + new ComponentAttributeSourceImpl( + (XMLComponentElement) attributeElement, + this, + getLocalBindingContext() + ) + ); + } + else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) { + attributeSources.add( + new ManyToOneAttributeSourceImpl( + XMLManyToOneElement.class.cast( attributeElement ), + getLocalBindingContext() + ) + ); + } + else if ( XMLOneToOneElement.class.isInstance( attributeElement ) ) { + // todo : implement + } + else if ( XMLAnyElement.class.isInstance( attributeElement ) ) { + // todo : implement + } + else if ( XMLOneToManyElement.class.isInstance( attributeElement ) ) { + // todo : implement + } + else if ( XMLManyToManyElement.class.isInstance( attributeElement ) ) { + // todo : implement + } + } + return attributeSources; + } + + @Override + public boolean isVirtualAttribute() { + return false; + } + + @Override + public SingularAttributeNature getNature() { + return SingularAttributeNature.COMPONENT; + } + + @Override + public ExplicitHibernateTypeSource getTypeInformation() { + // does not support type information. + return null; + } + + @Override + public String getName() { + return componentElement.getName(); + } + + @Override + public boolean isSingular() { + return true; + } + + @Override + public String getPropertyAccessorName() { + return componentElement.getAccess(); + } + + @Override + public boolean isInsertable() { + return componentElement.isInsert(); + } + + @Override + public boolean isUpdatable() { + return componentElement.isUpdate(); + } + + @Override + public PropertyGeneration getGeneration() { + // todo : is this correct here? + return null; + } + + @Override + public boolean isLazy() { + return componentElement.isLazy(); + } + + @Override + public boolean isIncludedInOptimisticLocking() { + return componentElement.isOptimisticLock(); + } + + @Override + public Iterable metaAttributes() { + return Helper.buildMetaAttributeSources( componentElement.getMeta() ); + } + + @Override + public boolean areValuesIncludedInInsertByDefault() { + return isInsertable(); + } + + @Override + public boolean areValuesIncludedInUpdateByDefault() { + return isUpdatable(); + } + + @Override + public boolean areValuesNullableByDefault() { + return true; + } + + @Override + public List relationalValueSources() { + // none, they are defined on the simple sub-attributes + return null; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/RootEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/RootEntitySourceImpl.java index 8cefc7689a..b2ae01681c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/RootEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/RootEntitySourceImpl.java @@ -190,6 +190,11 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro }; } + @Override + public String getDiscriminatorMatchValue() { + return entityElement().getDiscriminatorValue(); + } + @Override public DiscriminatorSource getDiscriminatorSource() { final XMLHibernateMapping.XMLClass.XMLDiscriminator discriminatorElement = entityElement().getDiscriminator(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SubclassEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SubclassEntitySourceImpl.java index e6206525d9..e0fa0bbe06 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SubclassEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/SubclassEntitySourceImpl.java @@ -27,6 +27,7 @@ import org.hibernate.metamodel.source.binder.SubclassEntitySource; import org.hibernate.metamodel.source.binder.TableSource; import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLJoinedSubclassElement; +import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSubclassElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLUnionSubclassElement; /** @@ -89,4 +90,11 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement } return null; } + + @Override + public String getDiscriminatorMatchValue() { + return XMLSubclassElement.class.isInstance( entityElement() ) + ? ( (XMLSubclassElement) entityElement() ).getDiscriminatorValue() + : null; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AssociationResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AssociationResolver.java index 8164b5af4c..faf3bf251a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AssociationResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AssociationResolver.java @@ -60,7 +60,7 @@ class AssociationResolver { } AttributeBinding referencedAttributeBinding = attributeBinding.isPropertyReference() ? - entityBinding.getAttributeBinding( attributeBinding.getReferencedAttributeName() ) : + entityBinding.locateAttributeBinding( attributeBinding.getReferencedAttributeName() ) : entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(); if ( referencedAttributeBinding == null ) { // TODO: does attribute name include path w/ entity name? diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java index 6508052a44..0065d581a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java @@ -52,7 +52,7 @@ class AttributeTypeResolver { void resolve() { for ( EntityBinding entityBinding : metadata.getEntityBindings() ) { - for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindings() ) { + for ( AttributeBinding attributeBinding : entityBinding.attributeBindings() ) { resolveTypeInformation( attributeBinding ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java index 974e7ea5b4..70b2eeda6a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java @@ -424,7 +424,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } public void addCollection(AbstractPluralAttributeBinding pluralAttributeBinding) { - final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName(); + final String owningEntityName = pluralAttributeBinding.getContainer().getPathBase(); final String attributeName = pluralAttributeBinding.getAttribute().getName(); final String collectionRole = owningEntityName + '.' + attributeName; if ( collectionBindingMap.containsKey( collectionRole ) ) { @@ -535,7 +535,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { throw new MappingException( "Entity binding not known: " + entityName ); } // TODO: should this call EntityBinding.getReferencedAttributeBindingString), which does not exist yet? - AttributeBinding attributeBinding = entityBinding.getAttributeBinding( propertyName ); + AttributeBinding attributeBinding = entityBinding.locateAttributeBinding( propertyName ); if ( attributeBinding == null ) { throw new MappingException( "unknown property: " + entityName + '.' + propertyName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 4c82282401..605a2c6c88 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -100,7 +100,6 @@ import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.SimpleValueBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.relational.DerivedValue; -import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.Value; import org.hibernate.pretty.MessageHelper; import org.hibernate.property.BackrefPropertyAccessor; @@ -802,7 +801,7 @@ public abstract class AbstractEntityPersister loaderName = entityBinding.getCustomLoaderName(); int i = 0; - for ( org.hibernate.metamodel.relational.Column col : entityBinding.getBaseTable().getPrimaryKey().getColumns() ) { + for ( org.hibernate.metamodel.relational.Column col : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) { rootTableKeyColumnNames[i] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); if ( col.getReadFragment() == null ) { rootTableKeyColumnReaders[i] = rootTableKeyColumnNames[i]; @@ -813,7 +812,7 @@ public abstract class AbstractEntityPersister rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( col.getReadFragment(), factory ); } // TODO: Fix when HHH-6337 is fixed; for now assume entityBinding is the root - // identifierAliases[i] = col.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getBaseTable() ); + // identifierAliases[i] = col.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable() ); identifierAliases[i] = col.getAlias( factory.getDialect() ); i++; } @@ -878,7 +877,7 @@ public abstract class AbstractEntityPersister thisClassProperties.add( singularAttributeBinding ); - propertySubclassNames[i] = singularAttributeBinding.getEntityBinding().getEntity().getName(); + propertySubclassNames[i] = ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName(); int span = singularAttributeBinding.getSimpleValueSpan(); propertyColumnSpans[i] = span; @@ -983,7 +982,7 @@ public abstract class AbstractEntityPersister final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding; names.add( singularAttributeBinding.getAttribute().getName() ); - classes.add( singularAttributeBinding.getEntityBinding().getEntity().getName() ); + classes.add( ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName() ); boolean isDefinedBySubclass = ! thisClassProperties.contains( singularAttributeBinding ); definedBySubclass.add( isDefinedBySubclass ); propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct? diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index 7935f32e5b..e7a0032a10 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -467,8 +467,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { keyColumnNames = new String[joinSpan][]; // TODO: fix when EntityBinhding.getRootEntityBinding() exists (HHH-6337) - //final Table table = entityBinding.getRootEntityBinding().getBaseTable(); - final TableSpecification table = entityBinding.getBaseTable(); + //final Table table = entityBinding.getRootEntityBinding().getPrimaryTable(); + final TableSpecification table = entityBinding.getPrimaryTable(); qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() ); isInverseTable[0] = false; isNullableTable[0] = false; @@ -571,7 +571,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory ); // TODO: fix this when EntityBinding.getRootEntityBinding() is implemented; // for now, assume entityBinding is the root - //discriminatorAlias = column.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getBaseTable ); + //discriminatorAlias = column.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable ); discriminatorAlias = column.getAlias( factory.getDialect() ); discriminatorFormula = null; discriminatorFormulaTemplate = null; @@ -663,7 +663,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { //propertyTableNumbersByName.put( singularAttributeBinding.getName(), join ); propertyTableNumbersByNameAndSubclass.put( - singularAttributeBinding.getEntityBinding().getEntity().getName() + '.' + singularAttributeBinding.getAttribute().getName(), + singularAttributeBinding.getContainer().getPathBase() + '.' + singularAttributeBinding.getAttribute().getName(), join ); diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index 01b87c21dc..d4ba5c6a63 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -199,7 +199,7 @@ public class PropertyFactory { mappedUnsavedValue, getGetter( property ), (VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(), - getConstructor( property.getEntityBinding() ) + getConstructor( (EntityBinding) property.getContainer() ) ); boolean lazy = lazyAvailable && property.isLazy(); @@ -390,13 +390,13 @@ public class PropertyFactory { } private static Getter getGetter(AttributeBinding mappingProperty) { - if ( mappingProperty == null || mappingProperty.getEntityBinding().getEntity() == null ) { + if ( mappingProperty == null || mappingProperty.getContainer().getClassReference() == null ) { return null; } PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO ); return pa.getGetter( - mappingProperty.getEntityBinding().getEntity().getClassReference(), + mappingProperty.getContainer().getClassReference(), mappingProperty.getAttribute().getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java index 0540ccaa4a..c685de0972 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java @@ -294,7 +294,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer { // } //} - for ( AttributeBinding property : entityBinding.getAttributeBindings() ) { + for ( AttributeBinding property : entityBinding.attributeBindings() ) { Method method = getGetter( property ).getMethod(); if ( method != null && Modifier.isFinal( method.getModifiers() ) ) { LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName()); @@ -462,14 +462,14 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer { private Getter getGetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException { return getPropertyAccessor( mappedProperty ).getGetter( - mappedProperty.getEntityBinding().getEntity().getClassReference(), + mappedProperty.getContainer().getClassReference(), mappedProperty.getAttribute().getName() ); } private Setter getSetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException { return getPropertyAccessor( mappedProperty ).getSetter( - mappedProperty.getEntityBinding().getEntity().getClassReference(), + mappedProperty.getContainer().getClassReference(), mappedProperty.getAttribute().getName() ); } @@ -477,7 +477,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer { private PropertyAccessor getPropertyAccessor(AttributeBinding mappedProperty) throws MappingException { // TODO: Fix this then backrefs are working in new metamodel return PropertyAccessorFactory.getPropertyAccessor( - mappedProperty.getEntityBinding().getEntity().getClassReference(), + mappedProperty.getContainer().getClassReference(), mappedProperty.getPropertyAccessorName() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java index 04ece30937..db1afadfa4 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java @@ -28,6 +28,7 @@ import java.util.Iterator; import java.util.Set; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -61,12 +62,10 @@ import static org.junit.Assert.assertTrue; public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { private BasicServiceRegistryImpl serviceRegistry; - private MetadataSources sources; @Before public void setUp() { serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder().buildServiceRegistry(); - sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() ); } @After @@ -80,7 +79,9 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { @Test public void testSimpleEntityMapping() { - MetadataImpl metadata = addSourcesForSimpleEntityBinding( sources ); + MetadataSources sources = new MetadataSources( serviceRegistry ); + addSourcesForSimpleEntityBinding( sources ); + MetadataImpl metadata = (MetadataImpl) sources.buildMetadata(); EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() ); assertRoot( metadata, entityBinding ); assertIdAndSimpleProperty( entityBinding ); @@ -90,7 +91,9 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { @Test public void testSimpleVersionedEntityMapping() { - MetadataImpl metadata = addSourcesForSimpleVersionedEntityBinding( sources ); + MetadataSources sources = new MetadataSources( serviceRegistry ); + addSourcesForSimpleVersionedEntityBinding( sources ); + MetadataImpl metadata = (MetadataImpl) sources.buildMetadata(); EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() ); assertIdAndSimpleProperty( entityBinding ); @@ -100,12 +103,15 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { @Test public void testEntityWithManyToOneMapping() { - MetadataImpl metadata = addSourcesForManyToOne( sources ); + MetadataSources sources = new MetadataSources( serviceRegistry ); + addSourcesForSimpleEntityBinding( sources ); + addSourcesForManyToOne( sources ); + MetadataImpl metadata = (MetadataImpl) sources.buildMetadata(); EntityBinding simpleEntityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() ); assertIdAndSimpleProperty( simpleEntityBinding ); - Set referenceBindings = simpleEntityBinding.getAttributeBinding( "id" ) + Set referenceBindings = simpleEntityBinding.locateAttributeBinding( "id" ) .getEntityReferencingAttributeBindings(); assertEquals( "There should be only one reference binding", 1, referenceBindings.size() ); @@ -118,22 +124,41 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { Iterator it = entityWithManyToOneBinding.getEntityReferencingAttributeBindings() .iterator(); assertTrue( it.hasNext() ); - assertSame( entityWithManyToOneBinding.getAttributeBinding( "simpleEntity" ), it.next() ); + assertSame( entityWithManyToOneBinding.locateAttributeBinding( "simpleEntity" ), it.next() ); assertFalse( it.hasNext() ); } - public abstract MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources); + @Test + public void testSimpleEntityWithSimpleComponentMapping() { + MetadataSources sources = new MetadataSources( serviceRegistry ); + addSourcesForComponentBinding( sources ); + MetadataImpl metadata = (MetadataImpl) sources.buildMetadata(); + EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntityWithSimpleComponent.class.getName() ); + assertRoot( metadata, entityBinding ); + assertIdAndSimpleProperty( entityBinding ); - public abstract MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources); + ComponentAttributeBinding componentAttributeBinding = (ComponentAttributeBinding) entityBinding.locateAttributeBinding( "simpleComponent" ); + assertNotNull( componentAttributeBinding ); + assertSame( componentAttributeBinding.getAttribute().getSingularAttributeType(), componentAttributeBinding.getAttributeContainer() ); + assertEquals( SimpleEntityWithSimpleComponent.class.getName() + ".simpleComponent", componentAttributeBinding.getPathBase() ); + assertSame( entityBinding.getPrimaryTable(), componentAttributeBinding.getPrimaryTable() ); + assertNotNull( componentAttributeBinding.getComponent() ); + } - public abstract MetadataImpl addSourcesForManyToOne(MetadataSources sources); + public abstract void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources); + + public abstract void addSourcesForSimpleEntityBinding(MetadataSources sources); + + public abstract void addSourcesForManyToOne(MetadataSources sources); + + public abstract void addSourcesForComponentBinding(MetadataSources sources); protected void assertIdAndSimpleProperty(EntityBinding entityBinding) { assertNotNull( entityBinding ); assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier() ); assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ); - AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); + AttributeBinding idAttributeBinding = entityBinding.locateAttributeBinding( "id" ); assertNotNull( idAttributeBinding ); assertSame( idAttributeBinding, entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ); assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); @@ -152,11 +177,11 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { assertSame( Types.BIGINT, idDataType.getTypeCode() ); assertSame( LongType.INSTANCE.getName(), idDataType.getTypeName() ); - assertNotNull( entityBinding.getAttributeBinding( "name" ) ); - assertNotNull( entityBinding.getAttributeBinding( "name" ).getAttribute() ); - assertTrue( entityBinding.getAttributeBinding( "name" ).getAttribute().isSingular() ); + assertNotNull( entityBinding.locateAttributeBinding( "name" ) ); + assertNotNull( entityBinding.locateAttributeBinding( "name" ).getAttribute() ); + assertTrue( entityBinding.locateAttributeBinding( "name" ).getAttribute().isSingular() ); - SingularAttributeBinding nameBinding = (SingularAttributeBinding) entityBinding.getAttributeBinding( "name" ); + SingularAttributeBinding nameBinding = (SingularAttributeBinding) entityBinding.locateAttributeBinding( "name" ); assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); assertNotNull( nameBinding.getAttribute() ); assertNotNull( nameBinding.getValue() ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java index 2d907b2993..aeed08e742 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java @@ -32,19 +32,23 @@ import org.hibernate.metamodel.source.internal.MetadataImpl; * @author Hardy Ferentschik */ public class BasicAnnotationBindingTests extends AbstractBasicBindingTests { - public MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources) { + @Override + public void addSourcesForSimpleEntityBinding(MetadataSources sources) { sources.addAnnotatedClass( SimpleEntity.class ); - return (MetadataImpl) sources.buildMetadata(); } - public MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { + @Override + public void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { sources.addAnnotatedClass( SimpleVersionedEntity.class ); - return (MetadataImpl) sources.buildMetadata(); } - public MetadataImpl addSourcesForManyToOne(MetadataSources sources) { + @Override + public void addSourcesForManyToOne(MetadataSources sources) { sources.addAnnotatedClass( ManyToOneEntity.class ); - sources.addAnnotatedClass( SimpleEntity.class ); - return (MetadataImpl) sources.buildMetadata(); + } + + @Override + public void addSourcesForComponentBinding(MetadataSources sources) { + sources.addAnnotatedClass( SimpleEntityWithSimpleComponent.class ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java index 927354b15e..805dc4bab6 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java @@ -24,7 +24,6 @@ package org.hibernate.metamodel.binding; import org.hibernate.metamodel.MetadataSources; -import org.hibernate.metamodel.source.internal.MetadataImpl; /** * Basic tests of {@code hbm.xml} binding code @@ -32,19 +31,19 @@ import org.hibernate.metamodel.source.internal.MetadataImpl; * @author Steve Ebersole */ public class BasicHbmBindingTests extends AbstractBasicBindingTests { - public MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources) { + public void addSourcesForSimpleEntityBinding(MetadataSources sources) { sources.addResource( "org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); - return (MetadataImpl) sources.buildMetadata(); } - public MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { + public void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { sources.addResource( "org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" ); - return (MetadataImpl) sources.buildMetadata(); } - public MetadataImpl addSourcesForManyToOne(MetadataSources sources) { + public void addSourcesForManyToOne(MetadataSources sources) { sources.addResource( "org/hibernate/metamodel/binding/ManyToOneEntity.hbm.xml" ); - sources.addResource( "org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); - return (MetadataImpl) sources.buildMetadata(); + } + + public void addSourcesForComponentBinding(MetadataSources sources) { + sources.addResource( "org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml" ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml new file mode 100644 index 0000000000..af62001456 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.java new file mode 100644 index 0000000000..1ae7cd8901 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.java @@ -0,0 +1,92 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binding; + +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Steve Ebersole + */ +@Entity +public class SimpleEntityWithSimpleComponent { + @Id + private Long id; + private String name; + private SimpleComponent simpleComponent; + + public SimpleEntityWithSimpleComponent() { + } + + public SimpleEntityWithSimpleComponent(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public SimpleComponent getSimpleComponent() { + return simpleComponent; + } + + public void setSimpleComponent(SimpleComponent simpleComponent) { + this.simpleComponent = simpleComponent; + } + + @Embeddable + public static class SimpleComponent { + private String value1; + private String value2; + + public String getValue1() { + return value1; + } + + public void setValue1(String value1) { + this.value1 = value1; + } + + public String getValue2() { + return value2; + } + + public void setValue2(String value2) { + this.value2 = value2; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/AccessBindingTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/AccessBindingTest.java index ce79f62ccb..bfbe32b9f3 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/AccessBindingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/AccessBindingTest.java @@ -52,7 +52,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase { @Resources(annotatedClasses = { FieldAccess.class }) public void testDefaultFieldAccess() { EntityBinding binding = getEntityBinding( FieldAccess.class ); - assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); + assertEquals( "Wrong access type", "field", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() ); } @Entity @@ -69,7 +69,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase { @Resources(annotatedClasses = { PropertyAccess.class }) public void testDefaultPropertyAccess() { EntityBinding binding = getEntityBinding( PropertyAccess.class ); - assertEquals( "Wrong access type", "property", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); + assertEquals( "Wrong access type", "property", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() ); } @@ -105,11 +105,11 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase { @Resources(annotatedClasses = { MixedAccess.class }) public void testMixedAccess() { EntityBinding binding = getEntityBinding( MixedAccess.class ); - assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); + assertEquals( "Wrong access type", "field", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() ); assertEquals( "Wrong access type", "property", - binding.getAttributeBinding( "name" ).getPropertyAccessorName() + binding.locateAttributeBinding( "name" ).getPropertyAccessorName() ); } @@ -136,7 +136,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase { assertEquals( "Wrong access type", "field", - binding.getAttributeBinding( "id" ).getPropertyAccessorName() + binding.locateAttributeBinding( "id" ).getPropertyAccessorName() ); @@ -144,7 +144,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase { assertEquals( "Wrong access type", "property", - binding.getAttributeBinding( "name" ).getPropertyAccessorName() + binding.locateAttributeBinding( "name" ).getPropertyAccessorName() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTest.java index 74f905d6dd..a35651e39f 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/MappedSuperclassTest.java @@ -31,7 +31,6 @@ import javax.persistence.MappedSuperclass; import org.junit.Test; -import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.domain.NonEntity; @@ -54,7 +53,7 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase { // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) public void testSimpleAttributeOverrideInMappedSuperclass() { EntityBinding binding = getEntityBinding( MyEntity.class ); - SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.getAttributeBinding( "name" ); + SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "name" ); assertNotNull( "the name attribute should be bound to MyEntity", nameBinding ); Column column = (Column) nameBinding.getValue(); @@ -65,7 +64,7 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase { // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) public void testLastAttributeOverrideWins() { EntityBinding binding = getEntityBinding( MyEntity.class ); - SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.getAttributeBinding( "foo" ); + SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "foo" ); assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding ); Column column = (Column) fooBinding.getValue(); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/QuotedIdentifierTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/QuotedIdentifierTest.java index 517970329f..61ea86b750 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/QuotedIdentifierTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/QuotedIdentifierTest.java @@ -34,7 +34,7 @@ public class QuotedIdentifierTest extends BaseAnnotationBindingTestCase { } private void assertIdentifierEquals(String expected, EntityBinding realValue) { - org.hibernate.metamodel.relational.Table table = (org.hibernate.metamodel.relational.Table) realValue.getBaseTable(); + org.hibernate.metamodel.relational.Table table = (org.hibernate.metamodel.relational.Table) realValue.getPrimaryTable(); assertEquals( Identifier.toIdentifier( expected ), table.getTableName() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/TableNameTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/TableNameTest.java index e4c4fb2b02..d7faf047e2 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/TableNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/TableNameTest.java @@ -60,7 +60,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "TableNameTest$A", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); binding = getEntityBinding( B.class ); @@ -68,7 +68,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "TableNameTest$A", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); } @@ -93,7 +93,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "FOO", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); binding = getEntityBinding( JoinedB.class ); @@ -101,7 +101,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "TableNameTest$JoinedB", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); } @@ -126,7 +126,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "TableNameTest$TablePerClassA", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); binding = getEntityBinding( TablePerClassB.class ); @@ -134,7 +134,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase { assertEquals( "wrong table name", "TableNameTest$TablePerClassB", - ( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() + ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName() ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/UniqueConstraintBindingTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/UniqueConstraintBindingTest.java index ac51759f03..bccbc2ecc7 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/UniqueConstraintBindingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/UniqueConstraintBindingTest.java @@ -50,7 +50,7 @@ public class UniqueConstraintBindingTest extends BaseAnnotationBindingTestCase { @Resources(annotatedClasses = TableWithUniqueConstraint.class) public void testTableUniqueConstraints() { EntityBinding binding = getEntityBinding( TableWithUniqueConstraint.class ); - TableSpecification table = binding.getBaseTable(); + TableSpecification table = binding.getPrimaryTable(); Iterable uniqueKeyIterable = table.getUniqueKeys(); assertNotNull( uniqueKeyIterable ); int i = 0;