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 c15929e329..478fd14dda 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 @@ -70,12 +70,24 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, public SingularAttribute getOrCreateSingularAttribute(String name) { SingularAttribute attribute = (SingularAttribute) getAttribute( name ); if ( attribute == null ) { + attribute = new SingularAttributeImpl( name, this ); addAttribute( attribute ); } return attribute; } + @Override + public SingularAttribute getOrCreateComponentAttribute(String name) { + SingularAttribute attribute = (SingularAttribute) getAttribute( name ); + if ( attribute == null ) { + Component component = new Component( name, null ); + attribute = new SingularAttributeImpl( name, component ); + addAttribute( attribute ); + } + return attribute; + } + @Override public PluralAttribute getOrCreateBag(String name) { return getOrCreatePluralAttribute( name, PluralAttributeNature.BAG ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java index 2500eb6337..b48a75deb3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java @@ -26,7 +26,7 @@ package org.hibernate.metamodel.domain; import java.util.Set; /** - * Basic contract for any container holding attributes. This allows polymorphic handling of both + * Basic contract for any container holding attributes. This allows polymorphic handling of both * components and entities in terms of the attributes they hold. * * @author Steve Ebersole @@ -39,8 +39,19 @@ public interface AttributeContainer extends Type { */ public Set getAttributes(); + /** + * Retrieve an attribute by name. + * + * @param name The name of the attribute to retrieve. + * + * @return The attribute matching the given name, or null. + */ + public Attribute getAttribute(String name); + public SingularAttribute getOrCreateSingularAttribute(String name); + public SingularAttribute getOrCreateComponentAttribute(String name); + public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature); public PluralAttribute getOrCreateBag(String name); @@ -50,13 +61,4 @@ public interface AttributeContainer extends Type { public IndexedPluralAttribute getOrCreateList(String name); public IndexedPluralAttribute getOrCreateMap(String name); - - /** - * Retrieve an attribute by name. - * - * @param name The name of the attribute to retrieve. - * - * @return The attribute matching the given name, or null. - */ - public Attribute getAttribute(String name); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java index 735b62a472..131028b0a7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java @@ -152,11 +152,11 @@ public class ConfiguredClass { return mappedAttributes.values(); } - public Iterable getEmbeddedClasses() { - return embeddedClasses.values(); + public Map getEmbeddedClasses() { + return embeddedClasses; } - public MappedAttribute getMappedProperty(String propertyName) { + public MappedAttribute getMappedAttribute(String propertyName) { return mappedAttributes.get( propertyName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntityBinder.java index af68355340..7eb68f331b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/entity/EntityBinder.java @@ -23,10 +23,10 @@ */ package org.hibernate.metamodel.source.annotations.entity; -import javax.persistence.GenerationType; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.persistence.GenerationType; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; @@ -53,7 +53,9 @@ import org.hibernate.metamodel.binding.SimpleAttributeBinding; import org.hibernate.metamodel.binding.state.DiscriminatorBindingState; import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState; import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState; +import org.hibernate.metamodel.domain.AttributeContainer; import org.hibernate.metamodel.domain.Hierarchical; +import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.relational.Identifier; import org.hibernate.metamodel.relational.Schema; import org.hibernate.metamodel.relational.TableSpecification; @@ -119,6 +121,9 @@ public class EntityBinder { // bind all attributes - simple as well as associations bindAttributes( entityBinding ); + bindEmbeddedAttributes( entityBinding ); + + bindTableUniqueConstraints( entityBinding ); // last, but not least we initialize and register the new EntityBinding @@ -189,7 +194,7 @@ public class EntityBinder { ); SimpleAttribute discriminatorAttribute = SimpleAttribute.createDiscriminatorAttribute( typeAnnotations ); - bindSingleMappedAttribute( entityBinding, discriminatorAttribute ); + bindSingleMappedAttribute( entityBinding, entityBinding.getEntity(), discriminatorAttribute ); if ( !( discriminatorAttribute.getColumnValues() instanceof DiscriminatorColumnValues ) ) { throw new AssertionFailure( "Expected discriminator column values" ); @@ -471,7 +476,7 @@ public class EntityBinder { ); String idName = JandexHelper.getPropertyName( idAnnotation.target() ); - MappedAttribute idAttribute = entityClass.getMappedProperty( idName ); + MappedAttribute idAttribute = entityClass.getMappedAttribute( idName ); if ( !( idAttribute instanceof SimpleAttribute ) ) { throw new AssertionFailure( "Unexpected attribute type for id attribute" ); } @@ -547,29 +552,50 @@ public class EntityBinder { private void bindAttributes(EntityBinding entityBinding) { for ( MappedAttribute mappedAttribute : entityClass.getMappedAttributes() ) { if ( mappedAttribute instanceof AssociationAttribute ) { - bindAssociationAttribute( entityBinding, (AssociationAttribute) mappedAttribute ); + bindAssociationAttribute( + entityBinding, + entityBinding.getEntity(), + (AssociationAttribute) mappedAttribute + ); } else { - bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute ); + bindSingleMappedAttribute( + entityBinding, + entityBinding.getEntity(), + (SimpleAttribute) mappedAttribute + ); } } + } - for ( EmbeddedClass embeddedClass : entityClass.getEmbeddedClasses() ) { + private void bindEmbeddedAttributes(EntityBinding entityBinding) { + for ( Map.Entry entry : entityClass.getEmbeddedClasses().entrySet() ) { + String attributeName = entry.getKey(); + EmbeddedClass embeddedClass = entry.getValue(); + SingularAttribute component = entityBinding.getEntity().getOrCreateComponentAttribute( attributeName ); for ( MappedAttribute mappedAttribute : embeddedClass.getMappedAttributes() ) { if ( mappedAttribute instanceof AssociationAttribute ) { - bindAssociationAttribute( entityBinding, (AssociationAttribute) mappedAttribute ); + bindAssociationAttribute( + entityBinding, + component.getAttributeContainer(), + (AssociationAttribute) mappedAttribute + ); } else { - bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute ); + bindSingleMappedAttribute( + entityBinding, + component.getAttributeContainer(), + (SimpleAttribute) mappedAttribute + ); } } } } - private void bindAssociationAttribute(EntityBinding entityBinding, AssociationAttribute associationAttribute) { + private void bindAssociationAttribute(EntityBinding entityBinding, AttributeContainer container, AssociationAttribute associationAttribute) { switch ( associationAttribute.getAssociationType() ) { case MANY_TO_ONE: { - entityBinding.getEntity().getOrCreateSingularAttribute( associationAttribute.getName() ); + container.getOrCreateSingularAttribute( associationAttribute.getName() ); ManyToOneAttributeBinding manyToOneAttributeBinding = entityBinding.makeManyToOneAttributeBinding( associationAttribute.getName() ); @@ -593,13 +619,13 @@ public class EntityBinder { } } - private void bindSingleMappedAttribute(EntityBinding entityBinding, SimpleAttribute simpleAttribute) { + private void bindSingleMappedAttribute(EntityBinding entityBinding, AttributeContainer container, SimpleAttribute simpleAttribute) { if ( simpleAttribute.isId() ) { return; } String attributeName = simpleAttribute.getName(); - entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ); + container.getOrCreateSingularAttribute( attributeName ); SimpleAttributeBinding attributeBinding; if ( simpleAttribute.isDiscriminator() ) { diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java index 903b2b5c07..41d1564c98 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/entity/EmbeddableBindingTests.java @@ -44,7 +44,7 @@ public class EmbeddableBindingTests extends BaseAnnotationBindingTestCase { public void testEmbeddable() { buildMetadataSources( User.class, Address.class ); EntityBinding binding = getEntityBinding( User.class ); - assertNotNull( binding.getAttributeBinding( "city" ) ); + assertNotNull( binding.getAttributeBinding( "address" ) ); } @Entity diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java index b884b8bcf2..c922ad9040 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java @@ -81,7 +81,7 @@ public class GenericTypeDiscoveryTest extends BaseUnitTestCase { ConfiguredClass configuredClass = iter.next(); ClassInfo info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( Stuff.class.getName() ), info.name() ); - MappedAttribute property = configuredClass.getMappedProperty( "value" ); + MappedAttribute property = configuredClass.getMappedAttribute( "value" ); assertEquals( Price.class.getName(), property.getType() ); assertTrue( iter.hasNext() ); @@ -97,9 +97,9 @@ public class GenericTypeDiscoveryTest extends BaseUnitTestCase { info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( Item.class.getName() ), info.name() ); // properties are alphabetically ordered! - property = configuredClass.getMappedProperty( "owner" ); + property = configuredClass.getMappedAttribute( "owner" ); assertEquals( SomeGuy.class.getName(), property.getType() ); - property = configuredClass.getMappedProperty( "type" ); + property = configuredClass.getMappedAttribute( "type" ); assertEquals( PaperType.class.getName(), property.getType() ); assertTrue( iter.hasNext() ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/TypeDiscoveryTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/TypeDiscoveryTest.java index d096b3be02..d2023c52a7 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/TypeDiscoveryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/TypeDiscoveryTest.java @@ -75,13 +75,13 @@ public class TypeDiscoveryTest extends BaseUnitTestCase { Iterator iter = hierarchies.iterator().next().iterator(); ConfiguredClass configuredClass = iter.next(); - MappedAttribute property = configuredClass.getMappedProperty( "id" ); + MappedAttribute property = configuredClass.getMappedAttribute( "id" ); assertEquals( "Unexpected property type", "int", property.getType() ); - property = configuredClass.getMappedProperty( "string" ); + property = configuredClass.getMappedAttribute( "string" ); assertEquals( "Unexpected property type", String.class.getName(), property.getType() ); - property = configuredClass.getMappedProperty( "customString" ); + property = configuredClass.getMappedAttribute( "customString" ); assertEquals( "Unexpected property type", "my.custom.Type", property.getType() ); Map typeParameters = property.getTypeParameters();