From 84f65d4b41fe5af1ee7029dd34750f2cad09d45d Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Tue, 23 Oct 2012 12:14:40 -0700 Subject: [PATCH] HHH-7702 : Add support for collections of (aggregated) composite elements --- .../internal/builder/AttributeBuilder.java | 221 +++++++-- .../internal/builder/MetamodelBuilder.java | 8 +- .../hibernate/metamodel/internal/Binder.java | 201 ++++++-- ...BasicPluralAttributeElementSourceImpl.java | 2 +- ...oManyPluralAttributeElementSourceImpl.java | 2 +- .../PluralAttributeIndexSourceImpl.java | 4 +- .../annotations/ToOneAttributeSourceImpl.java | 6 +- .../AbstractPluralAttributeSourceImpl.java | 2 +- ...ositePluralAttributeElementSourceImpl.java | 85 +++- .../hbm/ManyToOneAttributeSourceImpl.java | 6 +- .../source/hbm/RootEntitySourceImpl.java | 3 +- ...=> AbstractAttributeBindingContainer.java} | 117 ++--- .../AbstractCompositeAttributeBinding.java | 189 -------- ...actCompositeAttributeBindingContainer.java | 258 +++++++++++ ...ralAttributeAssociationElementBinding.java | 31 +- .../AbstractPluralAttributeBinding.java | 7 +- .../AbstractSingularAttributeBinding.java | 5 + .../spi/binding/AttributeBinding.java | 2 + .../binding/AttributeBindingContainer.java | 171 +++++++ .../metamodel/spi/binding/Cascadeable.java | 2 +- .../binding/CompositeAttributeBinding.java | 433 +++++++++++++++++- .../CompositeAttributeBindingContainer.java | 35 ++ ...ompositePluralAttributeElementBinding.java | 72 ++- .../metamodel/spi/binding/EntityBinding.java | 245 +--------- .../spi/binding/EntityIdentifier.java | 28 +- .../binding/ManyToOneAttributeBinding.java | 20 +- .../MutableAttributeBindingContainer.java | 195 -------- ...onAggregatedCompositeAttributeBinding.java | 86 ---- ...ralAttributeAssociationElementBinding.java | 1 - .../PluralAttributeElementBinding.java | 14 +- .../binding/PluralAttributeIndexBinding.java | 2 +- .../metamodel/spi/domain/TypeNature.java | 2 +- ...CompositePluralAttributeElementSource.java | 3 +- .../source/PluralAttributeElementSource.java | 2 +- .../spi/source/SingularAttributeSource.java | 3 + .../AbstractCollectionPersister.java | 7 +- .../collection/OneToManyPersister.java | 3 - .../entity/AbstractEntityPersister.java | 7 +- .../org/hibernate/tuple/PropertyFactory.java | 26 +- .../component/AbstractComponentTuplizer.java | 14 +- .../tuple/component/ComponentMetamodel.java | 4 +- .../component/ComponentTuplizerFactory.java | 10 +- .../component/PojoComponentTuplizer.java | 12 +- .../entity/EmbeddableBindingTest.java | 9 +- .../binding/AbstractBasicBindingTests.java | 7 +- .../set/PersistentSetNonLazyTest.java | 1 - .../collection/set/PersistentSetTest.java | 1 - .../CompositeElementTest.java | 1 - .../values/ValuesBagCollectionEventTest.java | 1 - .../mapcompelem/MapCompositeElementTest.java | 1 - 50 files changed, 1576 insertions(+), 991 deletions(-) rename hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/{AggregatedCompositeAttributeBinding.java => AbstractAttributeBindingContainer.java} (70%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBinding.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBindingContainer.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBindingContainer.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MutableAttributeBindingContainer.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/NonAggregatedCompositeAttributeBinding.java diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/AttributeBuilder.java b/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/AttributeBuilder.java index 1a36f832a0..d0e71a547e 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/AttributeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/AttributeBuilder.java @@ -37,6 +37,7 @@ import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.Type; import org.hibernate.annotations.common.AssertionFailure; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.jpa.metamodel.internal.AbstractIdentifiableType; import org.hibernate.jpa.metamodel.internal.AbstractManagedType; @@ -46,9 +47,12 @@ import org.hibernate.jpa.metamodel.internal.MappedSuperclassTypeImpl; import org.hibernate.jpa.metamodel.internal.PluralAttributeImpl; import org.hibernate.jpa.metamodel.internal.SingularAttributeImpl; import org.hibernate.jpa.metamodel.internal.UnsupportedFeature; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; +import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; +import org.hibernate.metamodel.spi.binding.MapBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding; @@ -123,7 +127,7 @@ public class AttributeBuilder { return buildPluralAttribute( (PluralAttributeMetadata) attributeMetadata ); } final SingularAttributeMetadata singularAttributeMetadata = (SingularAttributeMetadata)attributeMetadata; - final Type metaModelType = getMetaModelType( singularAttributeMetadata.getAttributeTypeDescriptor() ); + final Type metaModelType = getSingularAttributeMetaModelType( singularAttributeMetadata.getAttributeTypeDescriptor() ); //noinspection unchecked return new SingularAttributeImpl( attributeMetadata.getName(), @@ -157,7 +161,7 @@ public class AttributeBuilder { attributeBinding, IDENTIFIER_MEMBER_RESOLVER ); - final Type metaModelType = getMetaModelType( attributeMetadata.getAttributeTypeDescriptor() ); + final Type metaModelType = getSingularAttributeMetaModelType( attributeMetadata.getAttributeTypeDescriptor() ); return new SingularAttributeImpl.Identifier( attributeBinding.getAttribute().getName(), attributeMetadata.getJavaType(), @@ -184,7 +188,7 @@ public class AttributeBuilder { attributeBinding, VERSION_MEMBER_RESOLVER ); - final Type metaModelType = getMetaModelType( attributeMetadata.getAttributeTypeDescriptor() ); + final Type metaModelType = getSingularAttributeMetaModelType( attributeMetadata.getAttributeTypeDescriptor() ); return new SingularAttributeImpl.Version( attributeBinding.getAttribute().getName(), attributeMetadata.getJavaType(), @@ -197,15 +201,22 @@ public class AttributeBuilder { @SuppressWarnings( "unchecked" ) private PluralAttribute buildPluralAttribute(PluralAttributeMetadata attributeMetadata) { - final Type elementType = getMetaModelType( attributeMetadata.getElementAttributeTypeDescriptor() ); + final PluralAttributeBinding pluralAttributeBinding = + (PluralAttributeBinding) attributeMetadata.getAttributeBinding(); + + final Type elementType = getPluralAttributeElementMetaModelType( + attributeMetadata.getElementAttributeTypeDescriptor() + ); if ( java.util.Map.class.isAssignableFrom( attributeMetadata.getJavaType() ) ) { - final Type keyType = getMetaModelType( attributeMetadata.getMapKeyAttributeTypeDescriptor() ); + final Type keyType = getPluralAttributeMapKeyMetaModelType( + attributeMetadata.getMapKeyAttributeTypeDescriptor() + ); return PluralAttributeImpl.builder( attributeMetadata.getJavaType() ) .owner( attributeMetadata.getOwnerType() ) .elementType( elementType ) .keyType( keyType ) .member( attributeMetadata.getMember() ) - .binding( (PluralAttributeBinding) attributeMetadata.getAttributeBinding() ) + .binding( pluralAttributeBinding ) .persistentAttributeType( attributeMetadata.getPersistentAttributeType() ) .build(); } @@ -213,43 +224,46 @@ public class AttributeBuilder { .owner( attributeMetadata.getOwnerType() ) .elementType( elementType ) .member( attributeMetadata.getMember() ) - .binding( (PluralAttributeBinding) attributeMetadata.getAttributeBinding() ) + .binding( pluralAttributeBinding ) .persistentAttributeType( attributeMetadata.getPersistentAttributeType() ) .build(); } @SuppressWarnings( "unchecked" ) - private Type getMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + private Type getSingularAttributeMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + AttributeBinding attributeBinding = + attributeTypeDescriptor + .getAttributeMetadata() + .getAttributeBinding(); + if ( !attributeBinding.getAttribute().isSingular() ) { + throw new IllegalArgumentException( + String.format( + "Expected singular attribute binding, but it was plural: %s", + attributeBinding.getAttribute().getName() + ) + ); + } switch ( attributeTypeDescriptor.getValueClassification() ) { case BASIC: { - return new BasicTypeImpl( - attributeTypeDescriptor.getBindableType(), - Type.PersistenceType.BASIC - ); + return getBasicAttributeMetaModelType( attributeTypeDescriptor ); } case ENTITY: { - final org.hibernate.type.EntityType type = (org.hibernate.type.EntityType) attributeTypeDescriptor.getHibernateType(); - return (Type) context.locateEntityTypeByName( type.getAssociatedEntityName() ); + return getEntityAttributeMetaModelType( attributeTypeDescriptor ); } case EMBEDDABLE: { - final EmbeddableTypeImpl embeddableType = new EmbeddableTypeImpl( - attributeTypeDescriptor.getBindableType(), - attributeTypeDescriptor.getAttributeMetadata().getOwnerType(), - (ComponentType) attributeTypeDescriptor.getHibernateType() - ); - context.registerEmbeddedableType( embeddableType ); - AggregatedCompositeAttributeBinding compositeAttributeBinding = - (AggregatedCompositeAttributeBinding) attributeTypeDescriptor - .getAttributeMetadata() - .getAttributeBinding(); - for ( AttributeBinding subAttributeBinding : compositeAttributeBinding.attributeBindings() ) { - final Attribute attribute = buildAttribute( embeddableType, subAttributeBinding ); - if ( attribute != null ) { - embeddableType.getBuilder().addAttribute( attribute ); - } + if ( ! ( attributeBinding instanceof CompositeAttributeBinding ) ) { + throw new IllegalArgumentException( + String.format( + "Unexpected type of attribute binding. Expected: %s; Actual: %s", + CompositeAttributeBinding.class.getName(), + attributeBinding.getClass().getName() + ) + ); } - embeddableType.lock(); - return embeddableType; + return getEmbeddableAttributeMetaModelType( + attributeTypeDescriptor, + (CompositeAttributeBinding) attributeBinding + ); } default: { throw new AssertionFailure( "Unknown type : " + attributeTypeDescriptor.getValueClassification() ); @@ -257,6 +271,145 @@ public class AttributeBuilder { } } + @SuppressWarnings( "unchecked" ) + private Type getPluralAttributeElementMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + final AttributeBinding attributeBinding = + attributeTypeDescriptor + .getAttributeMetadata() + .getAttributeBinding(); + if ( attributeBinding.getAttribute().isSingular() ) { + throw new IllegalArgumentException( + String.format( + "Expected plural attribute binding, but it was singular: %s", + attributeBinding.getAttribute().getName() + ) + ); + } + switch ( attributeTypeDescriptor.getValueClassification() ) { + case BASIC: { + return getBasicAttributeMetaModelType( attributeTypeDescriptor ); + } + case ENTITY: { + return getEntityAttributeMetaModelType( attributeTypeDescriptor ); + } + case EMBEDDABLE: { + final PluralAttributeBinding pluralAttributeBinding = (PluralAttributeBinding) attributeBinding; + final CompositePluralAttributeElementBinding compositePluralAttributeElementBinding = + (CompositePluralAttributeElementBinding) pluralAttributeBinding.getPluralAttributeElementBinding(); + return getEmbeddableAttributeMetaModelType( + attributeTypeDescriptor, + compositePluralAttributeElementBinding.getCompositeAttributeBindingContainer() + ); + } + default: { + throw new AssertionFailure( "Unknown type : " + attributeTypeDescriptor.getValueClassification() ); + } + } + } + + @SuppressWarnings( "unchecked" ) + private Type getPluralAttributeMapKeyMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + final AttributeBinding attributeBinding = + attributeTypeDescriptor + .getAttributeMetadata() + .getAttributeBinding(); + if ( attributeBinding.getAttribute().isSingular() ) { + throw new IllegalArgumentException( + String.format( + "Expected plural attribute binding, but it was singular: %s", + attributeBinding.getAttribute().getName() + ) + ); + } + if ( ! ( attributeBinding instanceof MapBinding ) ) { + throw new IllegalArgumentException( + String.format( + "Expected a map binding: %s", + attributeBinding.getAttribute().getName() + ) + ); + } + switch ( attributeTypeDescriptor.getValueClassification() ) { + case BASIC: { + return getBasicAttributeMetaModelType( attributeTypeDescriptor ); + } + case ENTITY: { + return getEntityAttributeMetaModelType( attributeTypeDescriptor ); + } + case EMBEDDABLE: { + // TODO: Need to implement CompositePluralAttributeIndexBinding + // final MapBinding mapBinding = (MapBinding) attributeBinding; + // final CompositePluralAttributeIndexBinding pluralAttributeIndexBinding = + // (CompositePluralAttributeIndexBinding) mapBinding.getPluralAttributeIndexBinding(); + // return getEmbeddableAttributeMetaModelType( + // attributeTypeDescriptor, + // pluralAttributeIndexBinding.getCompositeAttributeBindingContainer(); + //); + throw new NotYetImplementedException( "Composite map indexes are not implemented yet." ); + } + default: { + throw new AssertionFailure( "Unknown type : " + attributeTypeDescriptor.getValueClassification() ); + } + } + } + + @SuppressWarnings( "unchecked" ) + private Type getBasicAttributeMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + checkCorrectValueClassification( attributeTypeDescriptor, AttributeTypeDescriptor.ValueClassification.BASIC ); + return new BasicTypeImpl( + attributeTypeDescriptor.getBindableType(), + Type.PersistenceType.BASIC + ); + } + + @SuppressWarnings( "unchecked" ) + private Type getEntityAttributeMetaModelType(AttributeTypeDescriptor attributeTypeDescriptor) { + checkCorrectValueClassification( attributeTypeDescriptor, AttributeTypeDescriptor.ValueClassification.ENTITY ); + final org.hibernate.type.EntityType type = (org.hibernate.type.EntityType) attributeTypeDescriptor.getHibernateType(); + return (Type) context.locateEntityTypeByName( type.getAssociatedEntityName() ); + } + + @SuppressWarnings( "unchecked" ) + private Type getEmbeddableAttributeMetaModelType( + AttributeTypeDescriptor attributeTypeDescriptor, + CompositeAttributeBindingContainer compositeAttributeBindingContainer) { + checkCorrectValueClassification( attributeTypeDescriptor, AttributeTypeDescriptor.ValueClassification.EMBEDDABLE ); + if ( ! compositeAttributeBindingContainer.isAggregated() ) { + throw new IllegalArgumentException( + "Composite attribute binding is not aggregated." + ); + } + final EmbeddableTypeImpl embeddableType = new EmbeddableTypeImpl( + attributeTypeDescriptor.getBindableType(), + attributeTypeDescriptor.getAttributeMetadata().getOwnerType(), + (ComponentType) attributeTypeDescriptor.getHibernateType() + ); + context.registerEmbeddedableType( embeddableType ); + for ( AttributeBinding subAttributeBinding : compositeAttributeBindingContainer.attributeBindings() ) { + final Attribute attribute = buildAttribute( embeddableType, subAttributeBinding ); + if ( attribute != null ) { + embeddableType.getBuilder().addAttribute( attribute ); + } + } + embeddableType.lock(); + return embeddableType; + } + + private void checkCorrectValueClassification( + AttributeTypeDescriptor attributeTypeDescriptor, + AttributeTypeDescriptor.ValueClassification expectedValueClassification) { + if ( attributeTypeDescriptor.getValueClassification() != expectedValueClassification ) { + throw new IllegalArgumentException( + String.format( + "Unexpected value classification for [%s]; expected:[%s] actual:[%s]", + attributeTypeDescriptor, + expectedValueClassification, + attributeTypeDescriptor.getValueClassification() + ) + ); + } + } + private EntityMetamodel getDeclarerEntityMetamodel(IdentifiableType ownerType) { final Type.PersistenceType persistenceType = ownerType.getPersistenceType(); if ( persistenceType == Type.PersistenceType.ENTITY) { @@ -344,7 +497,7 @@ public class AttributeBuilder { elementPersistentAttributeType = PersistentAttributeType.BASIC; persistentAttributeType = PersistentAttributeType.ELEMENT_COLLECTION; } - else if ( elementNature == PluralAttributeElementBinding.Nature.COMPONENT ) { + else if ( elementNature == PluralAttributeElementBinding.Nature.AGGREGATE ) { elementPersistentAttributeType = PersistentAttributeType.EMBEDDED; persistentAttributeType = PersistentAttributeType.ELEMENT_COLLECTION; } @@ -369,7 +522,7 @@ public class AttributeBuilder { else if ( indexNature == PluralAttributeIndexBinding.Nature.MANY_TO_MANY ) { keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE; } - else if ( indexNature == PluralAttributeIndexBinding.Nature.AGGREGATION ) { + else if ( indexNature == PluralAttributeIndexBinding.Nature.AGGREGATE ) { keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED; } else { diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/MetamodelBuilder.java b/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/MetamodelBuilder.java index 41c3974887..2fbfeb0cb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/MetamodelBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/metamodel/internal/builder/MetamodelBuilder.java @@ -44,11 +44,11 @@ import org.hibernate.jpa.metamodel.internal.JpaMetaModelPopulationSetting; import org.hibernate.jpa.metamodel.internal.MappedSuperclassTypeImpl; import org.hibernate.jpa.metamodel.internal.MetamodelImpl; import org.hibernate.jpa.metamodel.internal.UnsupportedFeature; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.HierarchyDetails; -import org.hibernate.metamodel.spi.binding.NonAggregatedCompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularNonAssociationAttributeBinding; import org.hibernate.metamodel.spi.domain.Entity; import org.hibernate.metamodel.spi.domain.Hierarchical; @@ -282,7 +282,8 @@ public class MetamodelBuilder { break; } case AGGREGATED_COMPOSITE: { - SingularNonAssociationAttributeBinding idAttributeBinding = hierarchyDetails.getEntityIdentifier().getAttributeBinding(); + CompositeAttributeBinding idAttributeBinding = + (CompositeAttributeBinding) hierarchyDetails.getEntityIdentifier().getAttributeBinding(); if ( idAttributeBinding != null ) { if ( idAttributeBinding.getAttribute().getAttributeContainer().equals( descriptor ) ) { //noinspection unchecked @@ -295,7 +296,8 @@ public class MetamodelBuilder { } default: { // nature == (non-aggregated) COMPOSITE - NonAggregatedCompositeAttributeBinding idAttributeBinding = (NonAggregatedCompositeAttributeBinding) hierarchyDetails.getEntityIdentifier().getAttributeBinding(); + CompositeAttributeBinding idAttributeBinding = + (CompositeAttributeBinding) hierarchyDetails.getEntityIdentifier().getAttributeBinding(); if ( idAttributeBinding != null ) { if ( idAttributeBinding.getAttribute().getAttributeContainer().equals( descriptor ) ) { Set idClassAttributes = new HashSet(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java index 899a0d6889..c060a92f08 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java @@ -43,6 +43,8 @@ import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.config.spi.ConfigurationService; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyles; import org.hibernate.id.EntityIdentifierNature; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentityGenerator; @@ -54,13 +56,15 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.ValueHolder; import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; import org.hibernate.metamodel.spi.MetadataImplementor; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBindingContainer; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.BasicPluralAttributeIndexBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; +import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityDiscriminator; import org.hibernate.metamodel.spi.binding.EntityIdentifier; @@ -71,8 +75,6 @@ import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.InheritanceType; import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.spi.binding.MetaAttribute; -import org.hibernate.metamodel.spi.binding.MutableAttributeBindingContainer; -import org.hibernate.metamodel.spi.binding.NonAggregatedCompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.OneToManyPluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding; @@ -105,6 +107,7 @@ import org.hibernate.metamodel.spi.source.AttributeSourceContainer; import org.hibernate.metamodel.spi.source.BasicPluralAttributeElementSource; import org.hibernate.metamodel.spi.source.ColumnSource; import org.hibernate.metamodel.spi.source.ComponentAttributeSource; +import org.hibernate.metamodel.spi.source.CompositePluralAttributeElementSource; import org.hibernate.metamodel.spi.source.ConstraintSource; import org.hibernate.metamodel.spi.source.DerivedValueSource; import org.hibernate.metamodel.spi.source.DiscriminatorSource; @@ -282,8 +285,8 @@ public class Binder { EntityBinding rootEntityBinding, AggregatedCompositeIdentifierSource identifierSource ) { // locate the attribute binding - final AggregatedCompositeAttributeBinding idAttributeBinding = - (AggregatedCompositeAttributeBinding) bindIdentifierAttribute( + final CompositeAttributeBinding idAttributeBinding = + (CompositeAttributeBinding) bindIdentifierAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); @@ -305,7 +308,7 @@ public class Binder { } private AttributeBinding bindAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final AttributeSource attributeSource) { // Return existing binding if available final String attributeName = attributeSource.getName(); @@ -323,7 +326,30 @@ public class Binder { } private void bindAttributes( - final MutableAttributeBindingContainer attributeBindingContainer, + final CompositeAttributeBindingContainer compositeAttributeBindingContainer, + final AttributeSourceContainer attributeSourceContainer + ) { + if ( compositeAttributeBindingContainer.getParentReference() == null ) { + bindAttributes( + (AttributeBindingContainer) compositeAttributeBindingContainer, + attributeSourceContainer + ); + } + else { + for ( final AttributeSource subAttributeSource : attributeSourceContainer.attributeSources() ) { + if ( ! subAttributeSource.getName().equals( compositeAttributeBindingContainer.getParentReference().getName() ) ) { + bindAttribute( + compositeAttributeBindingContainer, + subAttributeSource + ); + } + } + } + + } + + private void bindAttributes( + final AttributeBindingContainer attributeBindingContainer, final AttributeSourceContainer attributeSourceContainer ) { for ( final AttributeSource attributeSource : attributeSourceContainer.attributeSources() ) { bindAttribute( attributeBindingContainer, attributeSource ); @@ -331,7 +357,7 @@ public class Binder { } private AbstractPluralAttributeBinding bindBagAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { @@ -348,7 +374,7 @@ public class Binder { } private BasicAttributeBinding bindBasicAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final SingularAttributeSource attributeSource, SingularAttribute attribute ) { if ( attribute == null ) { @@ -359,7 +385,7 @@ public class Binder { attributeBindingContainer, attributeSource, attribute, - attributeBindingContainer.seekEntityBinding().getPrimaryTable() ); + attributeBindingContainer.getPrimaryTable() ); final BasicAttributeBinding attributeBinding = attributeBindingContainer.makeBasicAttributeBinding( attribute, @@ -393,13 +419,14 @@ public class Binder { ); } - private void bindBasicCollectionKey( + private void bindNonAssociationCollectionKey( final AbstractPluralAttributeBinding attributeBinding, final PluralAttributeSource attributeSource) { - if ( attributeSource.getElementSource().getNature() != PluralAttributeElementSource.Nature.BASIC ) { + if ( attributeSource.getElementSource().getNature() != PluralAttributeElementSource.Nature.BASIC && + attributeSource.getElementSource().getNature() != PluralAttributeElementSource.Nature.AGGREGATE) { throw new AssertionFailure( String.format( - "Expected basic attribute binding; instead got {%s}", + "Expected basic or aggregate attribute binding; instead got {%s}", attributeSource.getElementSource().getNature() ) ); @@ -456,6 +483,62 @@ public class Binder { } } + private void bindCompositeCollectionElement( + final CompositePluralAttributeElementBinding elementBinding, + final CompositePluralAttributeElementSource elementSource, + final String defaultElementJavaTypeName ) { + final PluralAttributeBinding pluralAttributeBinding = elementBinding.getPluralAttributeBinding(); + ValueHolder> defaultElementJavaClassReference = null; + // Create the aggregate type + // TODO: aggregateName should be set to elementSource.getPath() (which is currently not implemented) + // or Binder should define AttributeBindingContainer paths instead. + String aggregateName = pluralAttributeBinding.getAttribute().getRole() + ".element"; + final Aggregate aggregate; + if ( elementSource.getClassName() != null ) { + aggregate = new Aggregate( + aggregateName, + elementSource.getClassName(), + elementSource.getClassReference() != null ? + elementSource.getClassReference() : + bindingContext().makeClassReference( elementSource.getClassName() ), + null + ); + } + else { + defaultElementJavaClassReference = bindingContext().makeClassReference( defaultElementJavaTypeName ); + aggregate = new Aggregate( + aggregateName, + defaultElementJavaClassReference.getValue().getName(), + defaultElementJavaClassReference, + null + ); + } + final SingularAttribute parentAttribute = + StringHelper.isEmpty( elementSource.getParentReferenceAttributeName() ) ? + null : + aggregate.createSingularAttribute( elementSource.getParentReferenceAttributeName() ); + final CompositeAttributeBindingContainer compositeAttributeBindingContainer = + elementBinding.createCompositeAttributeBindingContainer( + aggregate, + pluralAttributeBinding.getMetaAttributeContext(), // TODO: should get this from elementSource + parentAttribute + ); + + bindAttributes( compositeAttributeBindingContainer, elementSource ); + Type resolvedType = metadata.getTypeResolver().getTypeFactory().component( + new ComponentMetamodel( compositeAttributeBindingContainer, false, false ) + ); + // TODO: binding the HibernateTypeDescriptor should be simplified since we know the class name already + bindHibernateTypeDescriptor( + elementBinding.getHibernateTypeDescriptor(), + aggregate.getClassName(), + null, + defaultElementJavaClassReference == null ? null : defaultElementJavaClassReference.getValue().getName() + ); + bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedType ); + elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) ); + } + private void bindCollectionIndex( final IndexedPluralAttributeBinding attributeBinding, final PluralAttributeIndexSource attributeSource, @@ -573,8 +656,8 @@ public class Binder { } } - private AggregatedCompositeAttributeBinding bindAggregatedCompositeAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + private CompositeAttributeBinding bindAggregatedCompositeAttribute( + final AttributeBindingContainer attributeBindingContainer, final ComponentAttributeSource attributeSource, SingularAttribute attribute, boolean isAttributeIdentifier) { @@ -617,7 +700,7 @@ public class Binder { null : composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() ); final NaturalIdMutability naturalIdMutability = attributeSource.getNaturalIdMutability(); - final AggregatedCompositeAttributeBinding attributeBinding = + final CompositeAttributeBinding attributeBinding = attributeBindingContainer.makeAggregatedCompositeAttributeBinding( attribute, referencingAttribute, @@ -627,6 +710,10 @@ public class Binder { naturalIdMutability, createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); + bindAttributes( attributeBinding, attributeSource ); + Type resolvedType = metadata.getTypeResolver().getTypeFactory().component( + new ComponentMetamodel( attributeBinding, isAttributeIdentifier, false ) + ); // TODO: binding the HibernateTypeDescriptor should be simplified since we know the class name already bindHibernateTypeDescriptor( attributeBinding.getHibernateTypeDescriptor(), @@ -634,20 +721,6 @@ public class Binder { null, defaultJavaClassReference == null ? null : defaultJavaClassReference.getValue().getName() ); - if ( referencingAttribute == null ) { - bindAttributes( attributeBinding, attributeSource ); - } - else { - for ( final AttributeSource subAttributeSource : attributeSource.attributeSources() ) { - // TODO: don't create a "parent" attribute binding??? - if ( ! subAttributeSource.getName().equals( referencingAttribute.getName() ) ) { - bindAttribute( attributeBinding, subAttributeSource ); - } - } - } - Type resolvedType = metadata.getTypeResolver().getTypeFactory().component( - new ComponentMetamodel( attributeBinding, isAttributeIdentifier, false ) - ); bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType ); return attributeBinding; } @@ -941,7 +1014,7 @@ public class Binder { } private SingularAttributeBinding bindIdentifierAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final SingularAttributeSource attributeSource) { return bindSingularAttribute( attributeBindingContainer, attributeSource, true ); } @@ -991,7 +1064,7 @@ public class Binder { private AbstractPluralAttributeBinding bindListAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { @@ -1010,15 +1083,14 @@ public class Binder { } private ManyToOneAttributeBinding bindManyToOneAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final ToOneAttributeSource attributeSource, SingularAttribute attribute ) { if( attribute == null ){ attribute = createSingularAttribute( attributeBindingContainer, attributeSource ); } // TODO: figure out which table is used (could be secondary table...) - final TableSpecification table = attributeBindingContainer.seekEntityBinding().getPrimaryTable(); - + final TableSpecification table = attributeBindingContainer.getPrimaryTable(); //find the referenced entitybinding ValueHolder< Class< ? >> referencedJavaTypeValue = createSingularAttributeJavaType( attribute ); @@ -1085,7 +1157,7 @@ public class Binder { extractColumnsFromRelationalValueBindings( attributeBinding.getRelationalValueBindings() ), determineForeignKeyTargetColumns( referencedEntityBinding, attributeSource ) ); - attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() ); + attributeBinding.setCascadeStyle( determineCascadeStyle( attributeSource.getCascadeStyles() ) ); attributeBinding.setFetchTiming( attributeSource.getFetchTiming() ); attributeBinding.setFetchStyle( attributeSource.getFetchStyle() ); attributeBinding.setUnWrapProxy( attributeSource.isUnWrapProxy() ); @@ -1119,7 +1191,7 @@ public class Binder { } private AbstractPluralAttributeBinding bindMapAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { @@ -1201,11 +1273,12 @@ public class Binder { SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME, rootEntityBinding.getEntity() ); - final NonAggregatedCompositeAttributeBinding syntheticAttributeBinding = + + final CompositeAttributeBinding syntheticAttributeBinding = rootEntityBinding.makeVirtualCompositeAttributeBinding( syntheticAttribute, - idAttributeBindings, - createMetaAttributeContext( rootEntityBinding, identifierSource.getMetaAttributeSources() ) + createMetaAttributeContext( rootEntityBinding, identifierSource.getMetaAttributeSources() ), + idAttributeBindings ); bindHibernateTypeDescriptor( syntheticAttributeBinding.getHibernateTypeDescriptor(), @@ -1257,7 +1330,31 @@ public class Binder { ); bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedElementType ); // no need to bind JDBC data types because element is referenced EntityBinding's ID - elementBinding.setCascadeStyles( elementSource.getCascadeStyles() ); + elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) ); + } + + // TODO: should this be moved to CascadeStyles as a static method? + // TODO: sources already factor in default cascade; should that be done here instead? + private CascadeStyle determineCascadeStyle(Iterable cascadeStyles) { + CascadeStyle cascadeStyleResult; + List cascadeStyleList = new ArrayList(); + for ( CascadeStyle style : cascadeStyles ) { + if ( style != CascadeStyles.NONE ) { + cascadeStyleList.add( style ); + } + } + if ( cascadeStyleList.isEmpty() ) { + cascadeStyleResult = CascadeStyles.NONE; + } + else if ( cascadeStyleList.size() == 1 ) { + cascadeStyleResult = cascadeStyleList.get( 0 ); + } + else { + cascadeStyleResult = new CascadeStyles.MultipleCascadeStyle( + cascadeStyleList.toArray( new CascadeStyle[ cascadeStyleList.size() ] ) + ); + } + return cascadeStyleResult; } private void bindOneToManyCollectionKey( @@ -1322,7 +1419,7 @@ public class Binder { } private AbstractPluralAttributeBinding bindPluralAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource ) { final PluralAttributeSource.Nature nature = attributeSource.getNature(); final PluralAttribute attribute = @@ -1381,7 +1478,7 @@ public class Binder { attributeBinding.setWhere( attributeSource.getWhere() ); if ( attributeSource.getElementSource().getNature() == PluralAttributeElementSource.Nature.BASIC ) { - bindBasicCollectionKey( attributeBinding, attributeSource ); + bindNonAssociationCollectionKey( attributeBinding, attributeSource ); bindBasicCollectionElement( ( BasicPluralAttributeElementBinding ) attributeBinding.getPluralAttributeElementBinding(), ( BasicPluralAttributeElementSource ) attributeSource.getElementSource(), @@ -1409,6 +1506,14 @@ public class Binder { defaultElementJavaTypeName ); } + else if ( attributeSource.getElementSource().getNature() == PluralAttributeElementSource.Nature.AGGREGATE ) { + bindNonAssociationCollectionKey( attributeBinding, attributeSource ); + bindCompositeCollectionElement( + (CompositePluralAttributeElementBinding) attributeBinding.getPluralAttributeElementBinding(), + (CompositePluralAttributeElementSource) attributeSource.getElementSource(), + defaultCollectionElementJavaTypeName( reflectedCollectionJavaTypes ) + ); + } else { throw new NotYetImplementedException( String.format( "Support for collection elements of type %s not yet implemented", @@ -1490,7 +1595,7 @@ public class Binder { } private AbstractPluralAttributeBinding bindSetAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { @@ -1531,7 +1636,7 @@ public class Binder { } private SingularAttributeBinding bindSingularAttribute( - final MutableAttributeBindingContainer attributeBindingContainer, + final AttributeBindingContainer attributeBindingContainer, final SingularAttributeSource attributeSource, boolean isIdentifierAttribute) { final SingularAttributeSource.Nature nature = attributeSource.getNature(); @@ -1547,8 +1652,6 @@ public class Binder { attribute ); case COMPOSITE: - // TODO: should this deal with both aggregated and non-aggegated - // attribute bindings? return bindAggregatedCompositeAttribute( attributeBindingContainer, ComponentAttributeSource.class.cast( attributeSource ), @@ -2363,7 +2466,7 @@ public class Binder { pluralAttributeBinding.getAttribute().getName(), getReferencedPropertyNameIfNotId( pluralAttributeBinding ), pluralAttributeBinding.getPluralAttributeElementBinding() - .getNature() == PluralAttributeElementBinding.Nature.COMPONENT + .getNature() == PluralAttributeElementBinding.Nature.AGGREGATE ); } @@ -2374,7 +2477,7 @@ public class Binder { final TypeFactory typeFactory = metadata.getTypeResolver().getTypeFactory(); final String role = pluralAttributeBinding.getAttribute().getRole(); final String propertyRef = getReferencedPropertyNameIfNotId( pluralAttributeBinding ); - final boolean embedded = pluralAttributeBinding.getPluralAttributeElementBinding().getNature() == PluralAttributeElementBinding.Nature.COMPONENT; + final boolean embedded = pluralAttributeBinding.getPluralAttributeElementBinding().getNature() == PluralAttributeElementBinding.Nature.AGGREGATE; switch ( nature ){ case BAG: return typeFactory.bag( role, propertyRef, embedded ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/BasicPluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/BasicPluralAttributeElementSourceImpl.java index bd1eefad98..848c865266 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/BasicPluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/BasicPluralAttributeElementSourceImpl.java @@ -31,7 +31,7 @@ public class BasicPluralAttributeElementSourceImpl implements BasicPluralAttribu return Nature.BASIC; } else if ( MappedAttribute.Nature.ELEMENT_COLLECTION_EMBEDDABLE.equals( associationAttribute.getNature() ) ) { - return Nature.COMPONENT; + return Nature.AGGREGATE; } else { throw new AssertionError( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java index 835c584fc0..80876bf47e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java @@ -72,7 +72,7 @@ public class OneToManyPluralAttributeElementSourceImpl implements OneToManyPlura return Nature.BASIC; } case ELEMENT_COLLECTION_EMBEDDABLE: { - return Nature.COMPONENT; + return Nature.AGGREGATE; } default: { throw new AssertionFailure( "Unexpected attribute nature: " + associationAttribute.getNature() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeIndexSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeIndexSourceImpl.java index 93d55c9386..8e7cc3ea9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeIndexSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeIndexSourceImpl.java @@ -49,8 +49,8 @@ public class PluralAttributeIndexSourceImpl implements PluralAttributeIndexSourc switch ( indexedPluralAttributeSource.getElementSource().getNature() ) { case BASIC: return PluralAttributeIndexBinding.Nature.BASIC; - case COMPONENT: - return PluralAttributeIndexBinding.Nature.AGGREGATION; + case AGGREGATE: + return PluralAttributeIndexBinding.Nature.AGGREGATE; case MANY_TO_ANY: return PluralAttributeIndexBinding.Nature.MANY_TO_ANY; case MANY_TO_MANY: diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java index 738a12db73..f484a16920 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java @@ -40,7 +40,7 @@ import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttri import org.hibernate.metamodel.internal.source.annotations.util.EnumConversionHelper; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource; @@ -86,8 +86,8 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem @Override public List getDefaultNamingStrategies( final String entityName, final String tableName, final AttributeBinding referencedAttributeBinding) { - if ( AggregatedCompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) { - AggregatedCompositeAttributeBinding compositeAttributeBinding = AggregatedCompositeAttributeBinding.class.cast( + if ( CompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) { + CompositeAttributeBinding compositeAttributeBinding = CompositeAttributeBinding.class.cast( referencedAttributeBinding ); List result = new ArrayList( ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java index 5d986b342e..51930f2228 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java @@ -26,7 +26,6 @@ package org.hibernate.metamodel.internal.source.hbm; import java.util.Collections; import java.util.Map; -import org.hibernate.FetchMode; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; @@ -101,6 +100,7 @@ public abstract class AbstractPluralAttributeSourceImpl else if ( pluralAttributeElement.getCompositeElement() != null ) { return new CompositePluralAttributeElementSourceImpl( sourceMappingDocument(), + pluralAttributeElement, pluralAttributeElement.getCompositeElement() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/CompositePluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/CompositePluralAttributeElementSourceImpl.java index 6bf2df5818..f2c39b7395 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/CompositePluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/CompositePluralAttributeElementSourceImpl.java @@ -27,33 +27,48 @@ import java.util.ArrayList; import java.util.List; import org.hibernate.EntityMode; +import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.ValueHolder; +import org.hibernate.jaxb.spi.hbm.JaxbAnyElement; import org.hibernate.jaxb.spi.hbm.JaxbCompositeElementElement; +import org.hibernate.jaxb.spi.hbm.JaxbManyToOneElement; +import org.hibernate.jaxb.spi.hbm.JaxbNestedCompositeElementElement; +import org.hibernate.jaxb.spi.hbm.JaxbPropertyElement; import org.hibernate.jaxb.spi.hbm.JaxbTuplizerElement; +import org.hibernate.jaxb.spi.hbm.PluralAttributeElement; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.CompositePluralAttributeElementSource; import org.hibernate.metamodel.spi.source.LocalBindingContext; +import org.hibernate.metamodel.spi.source.SingularAttributeSource; /** * @author Steve Ebersole + * @author Gail Badner */ public class CompositePluralAttributeElementSourceImpl extends AbstractHbmSourceNode implements CompositePluralAttributeElementSource { + private final PluralAttributeElement pluralAttributeElement; private final JaxbCompositeElementElement compositeElement; + private final List attributeSources; public CompositePluralAttributeElementSourceImpl( MappingDocument mappingDocument, + PluralAttributeElement pluralAttributeElement, JaxbCompositeElementElement compositeElement) { super( mappingDocument ); + this.pluralAttributeElement = pluralAttributeElement; this.compositeElement = compositeElement; + this.attributeSources = buildAttributeSources( mappingDocument, compositeElement ); } @Override public Nature getNature() { - return Nature.COMPONENT; + return Nature.AGGREGATE; } @Override @@ -95,15 +110,25 @@ public class CompositePluralAttributeElementSourceImpl @Override public List attributeSources() { + return attributeSources; + } + + private static List buildAttributeSources( + MappingDocument mappingDocument, + JaxbCompositeElementElement compositeElement) { List attributeSources = new ArrayList(); -// for ( Object attribute : compositeElement .getPropertyOrManyToOneOrAny() ) { -// -// } - compositeElement.getAny(); - compositeElement.getManyToOne(); - compositeElement.getNestedCompositeElement(); - compositeElement.getProperty(); - //todo implement + for( final JaxbAnyElement element : compositeElement.getAny() ) { + attributeSources.add( buildAttributeSource( mappingDocument, element ) ); + } + for( final JaxbManyToOneElement element : compositeElement.getManyToOne() ) { + attributeSources.add( buildAttributeSource( mappingDocument, element ) ); + } + for( final JaxbNestedCompositeElementElement element : compositeElement.getNestedCompositeElement() ) { + attributeSources.add( buildAttributeSource( mappingDocument, element ) ); + } + for( final JaxbPropertyElement element : compositeElement.getProperty() ) { + attributeSources.add( buildAttributeSource( mappingDocument, element ) ); + } return attributeSources; } @@ -111,4 +136,46 @@ public class CompositePluralAttributeElementSourceImpl public LocalBindingContext getLocalBindingContext() { return bindingContext(); } + + @Override + public Iterable getCascadeStyles() { + return Helper.interpretCascadeStyles( pluralAttributeElement.getCascade(), bindingContext() ); + } + + private static AttributeSource buildAttributeSource( + MappingDocument sourceMappingDocument, + JaxbAnyElement attributeElement) { + // todo : implement + throw new NotYetImplementedException(); + } + + private static SingularAttributeSource buildAttributeSource( + MappingDocument sourceMappingDocument, + JaxbPropertyElement attributeElement) { + return new PropertyAttributeSourceImpl( + sourceMappingDocument, + attributeElement, + null, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID + ); + } + + private static AttributeSource buildAttributeSource( + MappingDocument sourceMappingDocument, + JaxbManyToOneElement attributeElement) { + return new ManyToOneAttributeSourceImpl( + sourceMappingDocument, + JaxbManyToOneElement.class.cast( attributeElement ), + null, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID + ); + } + + private static AttributeSource buildAttributeSource( + MappingDocument sourceMappingDocument, + JaxbNestedCompositeElementElement attributeElement) { + // todo : implement + throw new NotYetImplementedException(); + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java index 67bdcf3aed..98454fdee8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java @@ -33,7 +33,7 @@ import org.hibernate.jaxb.spi.hbm.JaxbColumnElement; import org.hibernate.jaxb.spi.hbm.JaxbManyToOneElement; import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.internal.Binder; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.relational.Value; @@ -275,8 +275,8 @@ class ManyToOneAttributeSourceImpl extends AbstractHbmSourceNode implements ToOn @Override public List getDefaultNamingStrategies(final String entityName, final String tableName, final AttributeBinding referencedAttributeBinding) { - if ( AggregatedCompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) { - AggregatedCompositeAttributeBinding compositeAttributeBinding = AggregatedCompositeAttributeBinding.class.cast( + if ( CompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) { + CompositeAttributeBinding compositeAttributeBinding = CompositeAttributeBinding.class.cast( referencedAttributeBinding ); List result = new ArrayList(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java index 9de85dcdac..7e29f5fdf3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java @@ -29,6 +29,7 @@ import java.util.List; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.TruthValue; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.id.EntityIdentifierNature; import org.hibernate.internal.util.StringHelper; @@ -449,7 +450,7 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro attributeSources.add( new IdentifierKeyAttributeSourceImpl( sourceMappingDocument(), keyProperty ) ); } for (JaxbKeyManyToOneElement element : compositeIdElement().getKeyManyToOne()){ - //todo: implement + throw new NotYetImplementedException( "key-many-to-one is not supported yet" ); } return attributeSources; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AggregatedCompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractAttributeBindingContainer.java similarity index 70% rename from hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AggregatedCompositeAttributeBinding.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractAttributeBindingContainer.java index 2bd2f8fb84..2518240f37 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AggregatedCompositeAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractAttributeBindingContainer.java @@ -23,71 +23,71 @@ */ package org.hibernate.metamodel.spi.binding; -import java.util.LinkedHashMap; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.hibernate.mapping.PropertyGeneration; -import org.hibernate.metamodel.spi.domain.Aggregate; import org.hibernate.metamodel.spi.domain.PluralAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute; +import org.hibernate.metamodel.spi.relational.TableSpecification; +import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.MetaAttributeContext; /** - * A composite attribute binding for an attribute that can be mapped - * to a single entity attribute by means of an actual component class - * that aggregates the tuple values. - * - * @todo should this be named something like AggregationAttributebinding instead? - * * @author Gail Badner */ -public class AggregatedCompositeAttributeBinding - extends AbstractCompositeAttributeBinding - implements MutableAttributeBindingContainer { - private final Map attributeBindingMap = new LinkedHashMap(); - private final SingularAttribute parentReference; +public abstract class AbstractAttributeBindingContainer implements AttributeBindingContainer { - public AggregatedCompositeAttributeBinding( - AttributeBindingContainer container, - SingularAttribute attribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - SingularAttribute parentReference) { - super( - container, - attribute, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext - ); - if ( ! attribute.getSingularAttributeType().isAggregate() ) { - throw new IllegalArgumentException( "Expected the attribute type to be a component" ); + protected abstract Map attributeBindingMapInternal(); + + @Override + public AttributeBinding locateAttributeBinding(String name) { + return attributeBindingMapInternal().get( name ); + } + + @Override + public AttributeBinding locateAttributeBinding(List values) { + for ( AttributeBinding attributeBinding : attributeBindingMapInternal().values() ) { + if ( !SingularAttributeBinding.class.isInstance( attributeBinding ) ) { + continue; + } + SingularAttributeBinding basicAttributeBinding = (SingularAttributeBinding) attributeBinding; + + List attributeValues = new ArrayList(); + for ( RelationalValueBinding relationalBinding : basicAttributeBinding.getRelationalValueBindings() ) { + attributeValues.add( relationalBinding.getValue() ); + } + + if ( attributeValues.equals( values ) ) { + return attributeBinding; + } } - this.parentReference = parentReference; + return null; } @Override - public boolean isAggregated() { - return true; + public Class getClassReference() { + return getAttributeContainer().getClassReference(); } - public Aggregate getComposite() { - return (Aggregate) getAttribute().getSingularAttributeType(); - } - public SingularAttribute getParentReference() { - return parentReference; + @Override + public int attributeBindingSpan() { + return attributeBindingMapInternal().size(); } @Override - protected Map attributeBindingMapInternal() { - return attributeBindingMap; + public Iterable attributeBindings() { + return attributeBindingMapInternal().values(); + } + + protected void collectRelationalValueBindings(List valueBindings) { + for ( AttributeBinding subAttributeBinding : attributeBindings() ) { + if ( AbstractSingularAttributeBinding.class.isInstance( subAttributeBinding ) ) { + ( (AbstractSingularAttributeBinding) subAttributeBinding ).collectRelationalValueBindings( valueBindings ); + } + } } @Override @@ -97,7 +97,7 @@ public class AggregatedCompositeAttributeBinding String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, - NaturalIdMutability naturalIdMutability, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, PropertyGeneration generation) { final BasicAttributeBinding binding = new BasicAttributeBinding( @@ -117,28 +117,29 @@ public class AggregatedCompositeAttributeBinding protected void registerAttributeBinding(AttributeBinding attributeBinding) { // todo : hook this into the EntityBinding notion of "entity referencing attribute bindings" - attributeBindingMap.put( attributeBinding.getAttribute().getName(), attributeBinding ); + attributeBindingMapInternal().put( attributeBinding.getAttribute().getName(), attributeBinding ); } @Override - public AggregatedCompositeAttributeBinding makeAggregatedCompositeAttributeBinding( + public CompositeAttributeBinding makeAggregatedCompositeAttributeBinding( SingularAttribute attribute, SingularAttribute parentReferenceAttribute, String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, - NaturalIdMutability naturalIdMutability, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext) { - final AggregatedCompositeAttributeBinding binding = new AggregatedCompositeAttributeBinding( - this, - attribute, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext, - parentReferenceAttribute - ); + final CompositeAttributeBinding binding = + CompositeAttributeBinding.createAggregatedCompositeAttributeBinding( + this, + attribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + parentReferenceAttribute + ); registerAttributeBinding( binding ); return binding; } @@ -149,7 +150,7 @@ public class AggregatedCompositeAttributeBinding String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, - NaturalIdMutability naturalIdMutability, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, EntityBinding referencedEntityBinding, SingularAttributeBinding referencedAttributeBinding, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBinding.java deleted file mode 100644 index 6342d71ab7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBinding.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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.spi.binding; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.hibernate.metamodel.spi.domain.AttributeContainer; -import org.hibernate.metamodel.spi.domain.SingularAttribute; -import org.hibernate.metamodel.spi.source.MetaAttributeContext; - -/** - * @author Steve Ebersole - */ -public abstract class AbstractCompositeAttributeBinding - extends AbstractSingularAttributeBinding - implements CompositeAttributeBinding { - private final String path; - - protected AbstractCompositeAttributeBinding( - AttributeBindingContainer container, - SingularAttribute attribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext) { - super( - container, - attribute, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext - ); - - this.path = container.getPathBase() + '.' + attribute.getName(); - - } - - @Override - public List getRelationalValueBindings() { - final List bindings = new ArrayList(); - collectRelationalValueBindings( bindings ); - return bindings; - } - - @Override - protected void collectRelationalValueBindings(List valueBindings) { - for ( AttributeBinding subAttributeBinding : attributeBindings() ) { - if ( AbstractSingularAttributeBinding.class.isInstance( subAttributeBinding ) ) { - ( (AbstractSingularAttributeBinding) subAttributeBinding ).collectRelationalValueBindings( valueBindings ); - } - } - } - - @Override - public EntityBinding seekEntityBinding() { - return getContainer().seekEntityBinding(); - } - - @Override - public String getPathBase() { - return path; - } - - @Override - public AttributeContainer getAttributeContainer() { - return (AttributeContainer) getAttribute().getSingularAttributeType(); - } - - @Override - public boolean isAssociation() { - return false; - } - - @Override - public boolean hasDerivedValue() { - // todo : not sure this is even relevant for components - return false; - } - - @Override - public boolean isNullable() { - // return false if there are any singular attributes are non-nullable - for ( AttributeBinding attributeBinding : attributeBindings() ) { - // only check singular attributes - if ( attributeBinding.getAttribute().isSingular() && - ! ( (SingularAttributeBinding) attributeBinding ).isNullable() ) { - return false; - } - } - return true; - } - - - @Override - public boolean isIncludedInInsert() { - // if the attribute is synthetic, this attribute binding (as a whole) is not insertable; - if ( getAttribute().isSynthetic() ) { - return false; - } - // otherwise, return true if there are any singular attributes that are included in the insert. - for ( AttributeBinding attributeBinding : attributeBindings() ) { - // only check singular attributes - if ( attributeBinding.getAttribute().isSingular() && - ( (SingularAttributeBinding) attributeBinding ).isIncludedInInsert() ) { - return true; - } - } - return false; - } - - @Override - public boolean isIncludedInUpdate() { - // if the attribute is synthetic, this attribute binding (as a whole) is not updateable; - if ( getAttribute().isSynthetic() ) { - return false; - } - // otherwise, return true if there are any singular attributes that are updatable; - for ( AttributeBinding attributeBinding : attributeBindings() ) { - // only check singular attributes - if ( attributeBinding.getAttribute().isSingular() && - ( (SingularAttributeBinding) attributeBinding ).isIncludedInUpdate() ) { - return true; - } - } - return false; - } - - protected abstract Map attributeBindingMapInternal(); - - @Override - public AttributeBinding locateAttributeBinding(String name) { - return attributeBindingMapInternal().get( name ); - } - - @Override - public AttributeBinding locateAttributeBinding(List values) { - for ( final AttributeBinding attributeBinding : attributeBindings() ) { - if ( !BasicAttributeBinding.class.isInstance( attributeBinding ) ) { - continue; - } - final BasicAttributeBinding basicAttributeBinding = (BasicAttributeBinding) attributeBinding; - if ( basicAttributeBinding.getRelationalValueBindings().equals( values ) ) { - return attributeBinding; - } - } - return null; - } - - @Override - public int attributeBindingSpan() { - return attributeBindingMapInternal().size(); - } - - @Override - public Iterable attributeBindings() { - return attributeBindingMapInternal().values(); - } - - @Override - public Class getClassReference() { - return getAttributeContainer().getClassReference(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBindingContainer.java new file mode 100644 index 0000000000..a9c8e7492e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractCompositeAttributeBindingContainer.java @@ -0,0 +1,258 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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.spi.binding; + +import java.util.List; + +import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.domain.AttributeContainer; +import org.hibernate.metamodel.spi.domain.PluralAttribute; +import org.hibernate.metamodel.spi.domain.SingularAttribute; +import org.hibernate.metamodel.spi.relational.TableSpecification; +import org.hibernate.metamodel.spi.source.MetaAttributeContext; + +/** + * A container for attribute bindings that make up composite grouping + * + * @author Gail Badner + */ +public abstract class AbstractCompositeAttributeBindingContainer + extends AbstractAttributeBindingContainer + implements CompositeAttributeBindingContainer { + private final EntityBinding entityBinding; + private final AttributeContainer attributeContainer; + private final TableSpecification primaryTable; + private final String path; + private final MetaAttributeContext metaAttributeContext; + private final SingularAttribute parentReference; + + protected AbstractCompositeAttributeBindingContainer( + EntityBinding entityBinding, + AttributeContainer attributeContainer, + TableSpecification primaryTable, + String path, + MetaAttributeContext metaAttributeContext, + SingularAttribute parentReference) { + this.entityBinding = entityBinding; + this.attributeContainer = attributeContainer; + this.primaryTable = primaryTable; + this.path = path; + this.metaAttributeContext = metaAttributeContext; + this.parentReference = parentReference; + } + + public SingularAttribute getParentReference() { + return parentReference; + } + + @Override + public String getPathBase() { + return path; + } + + @Override + public AttributeContainer getAttributeContainer() { + return attributeContainer; + } + + @Override + public EntityBinding seekEntityBinding() { + return entityBinding; + } + + @Override + public MetaAttributeContext getMetaAttributeContext() { + return metaAttributeContext; + } + + @Override + public TableSpecification getPrimaryTable() { + return primaryTable; + } + + protected abstract boolean isModifiable(); + + @Override + public BasicAttributeBinding makeBasicAttributeBinding( + SingularAttribute attribute, + List relationalValueBindings, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + PropertyGeneration generation) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeBasicAttributeBinding( + attribute, + relationalValueBindings, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + generation + ); + } + + @Override + public CompositeAttributeBinding makeAggregatedCompositeAttributeBinding( + SingularAttribute attribute, + SingularAttribute parentReferenceAttribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeAggregatedCompositeAttributeBinding( + attribute, + parentReferenceAttribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext + ); + } + + @Override + public ManyToOneAttributeBinding makeManyToOneAttributeBinding( + SingularAttribute attribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + EntityBinding referencedEntityBinding, + SingularAttributeBinding referencedAttributeBinding, + List valueBindings) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeManyToOneAttributeBinding( + attribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + referencedEntityBinding, + referencedAttributeBinding, + valueBindings + ); + } + + @Override + public BagBinding makeBagAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeBagAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } + + @Override + public ListBinding makeListAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext, + int base) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeListAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext, + base + ); + } + + @Override + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature elementNature, + PluralAttributeIndexBinding.Nature indexNature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeMapAttributeBinding( + attribute, + elementNature, + indexNature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } + + @Override + public SetBinding makeSetAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + if ( !isModifiable() ) { + throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." ); + } + return super.makeSetAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } +} \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeAssociationElementBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeAssociationElementBinding.java index ce330f5b3e..0f18f4698c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeAssociationElementBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeAssociationElementBinding.java @@ -37,7 +37,6 @@ public abstract class AbstractPluralAttributeAssociationElementBinding implements PluralAttributeAssociationElementBinding { private CascadeStyle cascadeStyle; - private boolean orphanDelete; AbstractPluralAttributeAssociationElementBinding(AbstractPluralAttributeBinding pluralAttributeBinding) { super( pluralAttributeBinding ); @@ -49,33 +48,7 @@ public abstract class AbstractPluralAttributeAssociationElementBinding } @Override - public void setCascadeStyles(Iterable cascadeStyles) { - List cascadeStyleList = new ArrayList(); - for ( CascadeStyle style : cascadeStyles ) { - if ( style != CascadeStyles.NONE ) { - cascadeStyleList.add( style ); - } - if ( style == CascadeStyles.DELETE_ORPHAN || - style == CascadeStyles.ALL_DELETE_ORPHAN ) { - orphanDelete = true; - } - } - - if ( cascadeStyleList.isEmpty() ) { - cascadeStyle = CascadeStyles.NONE; - } - else if ( cascadeStyleList.size() == 1 ) { - cascadeStyle = cascadeStyleList.get( 0 ); - } - else { - cascadeStyle = new CascadeStyles.MultipleCascadeStyle( - cascadeStyleList.toArray( new CascadeStyle[ cascadeStyleList.size() ] ) - ); - } - } - - @Override - public boolean isOrphanDeleteEnabled() { - return orphanDelete; + public void setCascadeStyle(CascadeStyle cascadeStyle) { + this.cascadeStyle = cascadeStyle; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeBinding.java index f644740836..cc97295042 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractPluralAttributeBinding.java @@ -98,7 +98,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi case BASIC: { return new BasicPluralAttributeElementBinding( this ); } - case COMPONENT: { + case AGGREGATE: { return new CompositePluralAttributeElementBinding( this ); } case ONE_TO_MANY: { @@ -126,6 +126,11 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi return pluralAttributeElementBinding.getNature().isAssociation(); } + @Override + public boolean isCascadeable() { + return pluralAttributeElementBinding.getNature().isCascadeable(); + } + @Override public PluralAttributeKeyBinding getPluralAttributeKeyBinding() { return pluralAttributeKeyBinding; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java index 5dd31ca0c8..b30f68fd21 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java @@ -98,6 +98,11 @@ public abstract class AbstractSingularAttributeBinding return (SingularAttribute) super.getAttribute(); } + @Override + public boolean isCascadeable() { + return isAssociation(); + } + @Override public boolean isLazy() { return isLazy; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBinding.java index 06fc45d88f..48bbd8ee2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBinding.java @@ -58,6 +58,8 @@ public interface AttributeBinding { public boolean isAssociation(); + public boolean isCascadeable(); + public boolean isBackRef(); public boolean isBasicPropertyAccessor(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java index ca3631f126..879b1afabb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java @@ -25,7 +25,11 @@ package org.hibernate.metamodel.spi.binding; import java.util.List; +import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.spi.domain.AttributeContainer; +import org.hibernate.metamodel.spi.domain.PluralAttribute; +import org.hibernate.metamodel.spi.domain.SingularAttribute; +import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.MetaAttributeContext; @@ -105,4 +109,171 @@ public interface AttributeBindingContainer { * @return The meta-attribute context. */ public MetaAttributeContext getMetaAttributeContext(); + + + /** + * Return the table specification for the relational values of attributes + * directly contained by this attribute binding container. + * + * @return the table specification. + */ + public abstract TableSpecification getPrimaryTable(); + + /** + * Factory method for basic attribute bindings. + * + * @param attribute The attribute for which to make a binding. + * @param relationalValueBindings + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param lazy + * @param metaAttributeContext + * @param generation + * + * @return The attribute binding instance. + */ + public BasicAttributeBinding makeBasicAttributeBinding( + SingularAttribute attribute, + List relationalValueBindings, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + PropertyGeneration generation); + + /** + * Factory method for component attribute bindings. + * + * @param attribute The attribute for which to make a binding. + * @param parentReferenceAttribute + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param lazy + * @param metaAttributeContext + * + * @return The attribute binding instance. + */ + public CompositeAttributeBinding makeAggregatedCompositeAttributeBinding( + SingularAttribute attribute, + SingularAttribute parentReferenceAttribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext); + + /** + * Factory method for many-to-one attribute bindings. + * + * + * @param attribute The attribute for which to make a binding. + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param lazy + * @param metaAttributeContext + * @param referencedEntityBinding + * @param referencedAttributeBinding + * @param valueBindings + * + * @return The attribute binding instance. + */ + public ManyToOneAttributeBinding makeManyToOneAttributeBinding( + SingularAttribute attribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + EntityBinding referencedEntityBinding, + SingularAttributeBinding referencedAttributeBinding, + List valueBindings); + + /** + * Factory method for bag attribute bindings. + * + * + * @param attribute The attribute for which to make a binding. + * @param nature The nature of the collection elements. + * @param referencedAttributeBinding + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param metaAttributeContext + * + * @return The attribute binding instance. + */ + public BagBinding makeBagAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext); + + /** + * Factory method for list attribute bindings. + * + * + * @param attribute The attribute for which to make a binding. + * @param nature The nature of the collection elements. + * @param referencedAttributeBinding + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param metaAttributeContext + * @param base + * + * @return The attribute binding instance. + */ + public ListBinding makeListAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext, + int base); + + /** + * Factory method for map attribute bindings. + * + * + * @param attribute The attribute for which to make a binding. + * @param elementNature The nature of the collection elements. + * @param indexNature The nature of the collection indexes. + * @param referencedAttributeBinding + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param metaAttributeContext + * + * @return The attribute binding instance. + */ + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature elementNature, + PluralAttributeIndexBinding.Nature indexNature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext); + + /** + * Factory method for set attribute bindings. + * + * + * @param attribute The attribute for which to make a binding. + * @param nature The nature of the collection elements. + * @param referencedAttributeBinding + * @param propertyAccessorName + * @param includedInOptimisticLocking + * @param metaAttributeContext + * + * @return The attribute binding instance. + */ + public SetBinding makeSetAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/Cascadeable.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/Cascadeable.java index b32340ea1d..a2b1b605b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/Cascadeable.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/Cascadeable.java @@ -31,5 +31,5 @@ import org.hibernate.engine.spi.CascadeStyle; public interface Cascadeable { public CascadeStyle getCascadeStyle(); - public void setCascadeStyles(Iterable cascadeStyles); + public void setCascadeStyle(CascadeStyle cascadeStyle); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java index aec52643db..14dbd5e9ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java @@ -23,29 +23,444 @@ */ package org.hibernate.metamodel.spi.binding; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.domain.AttributeContainer; +import org.hibernate.metamodel.spi.domain.PluralAttribute; +import org.hibernate.metamodel.spi.domain.SingularAttribute; +import org.hibernate.metamodel.spi.relational.TableSpecification; +import org.hibernate.metamodel.spi.relational.Value; +import org.hibernate.metamodel.spi.source.MetaAttributeContext; + /** * A specialized binding contract for a singular attribute binding that * contains other attribute bindings. * * @author Gail Badner */ -public interface CompositeAttributeBinding - extends SingularNonAssociationAttributeBinding, AttributeBindingContainer { +public class CompositeAttributeBinding + extends AbstractSingularAttributeBinding + implements SingularNonAssociationAttributeBinding, CompositeAttributeBindingContainer { + + private final AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer; + + private CompositeAttributeBinding( + AttributeBindingContainer container, + SingularAttribute attribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer) { + super( + container, + attribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext + ); + this.compositeAttributeBindingContainer = compositeAttributeBindingContainer; + } + + public static CompositeAttributeBinding createAggregatedCompositeAttributeBinding( + AttributeBindingContainer container, + SingularAttribute attribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + SingularAttribute parentReference) { + AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer = + new AbstractCompositeAttributeBindingContainer( + container.seekEntityBinding(), + (AttributeContainer) attribute.getSingularAttributeType(), + container.getPrimaryTable(), + createContainerPath( container, attribute ), + metaAttributeContext, + parentReference) { + private final Map attributeBindingMap = + new LinkedHashMap(); + + @Override + protected boolean isModifiable() { + return true; + } + + @Override + protected Map attributeBindingMapInternal() { + return attributeBindingMap; + } + + @Override + public boolean isAggregated() { + return true; + } + }; + if ( ! attribute.getSingularAttributeType().isAggregate() ) { + throw new IllegalArgumentException( + "Cannot create an aggregated CompositeAttributeBindingContainer with a non-aggregate attribute type" + ); + } + return new CompositeAttributeBinding( + container, + attribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + compositeAttributeBindingContainer + ); + } + + // TODO: Get rid of this when non-aggregated composite IDs is no longer modelled as a CompositeAttributeBinding. + public static CompositeAttributeBinding createNonAggregatedCompositeAttributeBinding( + AttributeBindingContainer container, + SingularAttribute syntheticAttribute, + String propertyAccessorName, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + final List subAttributeBindings) { + AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer = + new AbstractCompositeAttributeBindingContainer( + container.seekEntityBinding(), + (AttributeContainer) syntheticAttribute.getSingularAttributeType(), + container.getPrimaryTable(), + createContainerPath( container, syntheticAttribute ), + metaAttributeContext, + null) { + private final Map attributeBindingMap = createUnmodifiableAttributeBindingMap( subAttributeBindings ); + + @Override + protected boolean isModifiable() { + return false; + } + + @Override + protected Map attributeBindingMapInternal() { + return this.attributeBindingMap; + } + + @Override + public boolean isAggregated() { + return false; + } + }; + if ( syntheticAttribute.getSingularAttributeType().isAggregate() ) { + throw new IllegalArgumentException( + "Cannot create a non-aggregated CompositeAttributeBindingContainer with an aggregate attribute type" + ); + } + return new CompositeAttributeBinding( + container, + syntheticAttribute, + propertyAccessorName, + false, + false, + naturalIdMutability, + metaAttributeContext, + compositeAttributeBindingContainer + ); + } + + private static Map createUnmodifiableAttributeBindingMap( + List subAttributeBindings) { + Map map = new LinkedHashMap( subAttributeBindings.size() ); + for ( AttributeBinding subAttributeBinding : subAttributeBindings ) { + map.put( subAttributeBinding.getAttribute().getName(), subAttributeBinding ); + } + return Collections.unmodifiableMap( map ); + } + + private static String createContainerPath(AttributeBindingContainer container, SingularAttribute attribute) { + return container.getPathBase() + '.' + attribute.getName(); + } /** * Can the composite attribute be mapped to a single entity * attribute by means of an actual component class that aggregates * the tuple values? * - * If {@code true} is returned, this instance can safely be cast - * to an {@link AggregatedCompositeAttributeBinding}. - * - * If {@code false} is returned, this instance can safely be cast - * to a {@link NonAggregatedCompositeAttributeBinding}. - * * @return true, if the attribute can be mapped to a single entity * attribute by means of an actual component class that aggregates * the tuple values; false, otherwise. */ - boolean isAggregated(); + public boolean isAggregated() { + return compositeAttributeBindingContainer.isAggregated(); + } + + public SingularAttribute getParentReference() { + return compositeAttributeBindingContainer.getParentReference(); + } + + @Override + public List getRelationalValueBindings() { + final List bindings = new ArrayList(); + collectRelationalValueBindings( bindings ); + return bindings; + } + + @Override + public boolean isAssociation() { + return false; + } + + @Override + public boolean hasDerivedValue() { + // todo : not sure this is even relevant for components + return false; + } + + @Override + public boolean isNullable() { + // return false if there are any singular attributes are non-nullable + for ( AttributeBinding attributeBinding : attributeBindings() ) { + // only check singular attributes + if ( attributeBinding.getAttribute().isSingular() && + ! ( (SingularAttributeBinding) attributeBinding ).isNullable() ) { + return false; + } + } + return true; + } + + + @Override + public boolean isIncludedInInsert() { + // if the attribute is synthetic, this attribute binding (as a whole) is not insertable; + if ( getAttribute().isSynthetic() ) { + return false; + } + // otherwise, return true if there are any singular attributes that are included in the insert. + for ( AttributeBinding attributeBinding : attributeBindings() ) { + // only check singular attributes + if ( attributeBinding.getAttribute().isSingular() && + ( (SingularAttributeBinding) attributeBinding ).isIncludedInInsert() ) { + return true; + } + } + return false; + } + + @Override + public boolean isIncludedInUpdate() { + // if the attribute is synthetic, this attribute binding (as a whole) is not updateable; + if ( getAttribute().isSynthetic() ) { + return false; + } + // otherwise, return true if there are any singular attributes that are updatable; + for ( AttributeBinding attributeBinding : attributeBindings() ) { + // only check singular attributes + if ( attributeBinding.getAttribute().isSingular() && + ( (SingularAttributeBinding) attributeBinding ).isIncludedInUpdate() ) { + return true; + } + } + return false; + } + + @Override + protected void collectRelationalValueBindings(List valueBindings) { + for ( AttributeBinding subAttributeBinding : attributeBindings() ) { + if ( AbstractSingularAttributeBinding.class.isInstance( subAttributeBinding ) ) { + ( (AbstractSingularAttributeBinding) subAttributeBinding ).collectRelationalValueBindings( valueBindings ); + } + } + } + + @Override + public String getPathBase() { + return compositeAttributeBindingContainer.getPathBase(); + } + + @Override + public AttributeContainer getAttributeContainer() { + return compositeAttributeBindingContainer.getAttributeContainer(); + } + + @Override + public Iterable attributeBindings() { + return compositeAttributeBindingContainer.attributeBindings(); + } + + @Override + public int attributeBindingSpan() { + return compositeAttributeBindingContainer.attributeBindingSpan(); + } + + @Override + public AttributeBinding locateAttributeBinding(String name) { + return compositeAttributeBindingContainer.locateAttributeBinding( name ); + } + + @Override + public AttributeBinding locateAttributeBinding(List values) { + return compositeAttributeBindingContainer.locateAttributeBinding( values ); + } + + @Override + public EntityBinding seekEntityBinding() { + return compositeAttributeBindingContainer.seekEntityBinding(); + } + + @Override + public Class getClassReference() { + return compositeAttributeBindingContainer.getClassReference(); + } + + @Override + public TableSpecification getPrimaryTable() { + return compositeAttributeBindingContainer.getPrimaryTable(); + } + + @Override + public BasicAttributeBinding makeBasicAttributeBinding( + SingularAttribute attribute, + List relationalValueBindings, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + PropertyGeneration generation) { + return compositeAttributeBindingContainer.makeBasicAttributeBinding( + attribute, + relationalValueBindings, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + generation + ); + } + + @Override + public CompositeAttributeBinding makeAggregatedCompositeAttributeBinding( + SingularAttribute attribute, + SingularAttribute parentReferenceAttribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext) { + return compositeAttributeBindingContainer.makeAggregatedCompositeAttributeBinding( + attribute, + parentReferenceAttribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext + ); + } + + @Override + public ManyToOneAttributeBinding makeManyToOneAttributeBinding( + SingularAttribute attribute, + String propertyAccessorName, + boolean includedInOptimisticLocking, + boolean lazy, + NaturalIdMutability naturalIdMutability, + MetaAttributeContext metaAttributeContext, + EntityBinding referencedEntityBinding, + SingularAttributeBinding referencedAttributeBinding, + List valueBindings) { + return compositeAttributeBindingContainer.makeManyToOneAttributeBinding( + attribute, + propertyAccessorName, + includedInOptimisticLocking, + lazy, + naturalIdMutability, + metaAttributeContext, + referencedEntityBinding, + referencedAttributeBinding, + valueBindings + ); + } + + @Override + public BagBinding makeBagAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + return compositeAttributeBindingContainer.makeBagAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } + + @Override + public ListBinding makeListAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext, + int base) { + return compositeAttributeBindingContainer.makeListAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext, + base + ); + } + + @Override + public MapBinding makeMapAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature elementNature, + PluralAttributeIndexBinding.Nature indexNature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + return compositeAttributeBindingContainer.makeMapAttributeBinding( + attribute, + elementNature, + indexNature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } + + @Override + public SetBinding makeSetAttributeBinding( + PluralAttribute attribute, + PluralAttributeElementBinding.Nature nature, + SingularAttributeBinding referencedAttributeBinding, + String propertyAccessorName, + boolean includedInOptimisticLocking, + MetaAttributeContext metaAttributeContext) { + return compositeAttributeBindingContainer.makeSetAttributeBinding( + attribute, + nature, + referencedAttributeBinding, + propertyAccessorName, + includedInOptimisticLocking, + metaAttributeContext + ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBindingContainer.java new file mode 100644 index 0000000000..3425d17b92 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBindingContainer.java @@ -0,0 +1,35 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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.spi.binding; + +import org.hibernate.metamodel.spi.domain.SingularAttribute; + +/** + * @author Gail Badner + */ +public interface CompositeAttributeBindingContainer + extends AttributeBindingContainer { + boolean isAggregated(); + SingularAttribute getParentReference(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositePluralAttributeElementBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositePluralAttributeElementBinding.java index ef0554461e..65c44952da 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositePluralAttributeElementBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositePluralAttributeElementBinding.java @@ -23,26 +23,90 @@ */ package org.hibernate.metamodel.spi.binding; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; + +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.metamodel.spi.domain.Aggregate; +import org.hibernate.metamodel.spi.domain.SingularAttribute; +import org.hibernate.metamodel.spi.source.MetaAttributeContext; /** - * Describes plural attributes of {@link org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding.Nature#COMPONENT} elements + * Describes plural attributes of {@link org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding.Nature#AGGREGATE} elements * * @author Steve Ebersole * @author Gail Badner */ -public class CompositePluralAttributeElementBinding extends AbstractPluralAttributeElementBinding { +public class CompositePluralAttributeElementBinding + extends AbstractPluralAttributeElementBinding + implements Cascadeable { + + private AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer; + private CascadeStyle cascadeStyle; + public CompositePluralAttributeElementBinding(AbstractPluralAttributeBinding binding) { super( binding ); } @Override public Nature getNature() { - return Nature.COMPONENT; + return Nature.AGGREGATE; + } + + public CompositeAttributeBindingContainer createCompositeAttributeBindingContainer( + Aggregate aggregate, + MetaAttributeContext metaAttributeContext, + SingularAttribute parentReference + ) { + compositeAttributeBindingContainer = + new AbstractCompositeAttributeBindingContainer( + getPluralAttributeBinding().getContainer().seekEntityBinding(), + aggregate, + getPluralAttributeBinding().getPluralAttributeKeyBinding().getCollectionTable(), + aggregate.getRoleBaseName(), + metaAttributeContext, + parentReference + ) { + final Map attributeBindingMap = new LinkedHashMap(); + + @Override + protected boolean isModifiable() { + return true; + } + + @Override + protected Map attributeBindingMapInternal() { + return attributeBindingMap; + } + + @Override + public boolean isAggregated() { + return true; + } + }; + return compositeAttributeBindingContainer; + } + + public CompositeAttributeBindingContainer getCompositeAttributeBindingContainer() { + return compositeAttributeBindingContainer; } @Override public List getRelationalValueBindings() { - return null; //To change body of implemented methods use File | Settings | File Templates. + final List bindings = new ArrayList(); + compositeAttributeBindingContainer.collectRelationalValueBindings( bindings ); + return bindings; + } + + @Override + public CascadeStyle getCascadeStyle() { + return cascadeStyle; + } + + @Override + public void setCascadeStyle(CascadeStyle cascadeStyle) { + this.cascadeStyle = cascadeStyle; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java index 90609fac90..e9ab95e43b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java @@ -35,10 +35,8 @@ import org.hibernate.EntityMode; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.collections.JoinedIterable; -import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.spi.domain.AttributeContainer; import org.hibernate.metamodel.spi.domain.Entity; -import org.hibernate.metamodel.spi.domain.PluralAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.source.JpaCallbackSource; @@ -54,7 +52,7 @@ import org.hibernate.tuple.entity.EntityTuplizer; * @author Hardy Ferentschik * @author Gail Badner */ -public class EntityBinding implements MutableAttributeBindingContainer { +public class EntityBinding extends AbstractAttributeBindingContainer { private static final String NULL_DISCRIMINATOR_MATCH_VALUE = "null"; private static final String NOT_NULL_DISCRIMINATOR_MATCH_VALUE = "not null"; @@ -223,6 +221,7 @@ public class EntityBinding implements MutableAttributeBindingContainer { this.entity = entity; } + @Override public TableSpecification getPrimaryTable() { return primaryTable; } @@ -298,18 +297,14 @@ public class EntityBinding implements MutableAttributeBindingContainer { return getEntity().getName(); } - @Override - public Class getClassReference() { - return getEntity().getClassReference(); - } - @Override public AttributeContainer getAttributeContainer() { return getEntity(); } - protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) { - attributeBindingMap.put( name, attributeBinding ); + @Override + protected Map attributeBindingMapInternal() { + return attributeBindingMap; } @Override @@ -491,72 +486,26 @@ public class EntityBinding implements MutableAttributeBindingContainer { return sb.toString(); } - @Override - public BasicAttributeBinding makeBasicAttributeBinding( - SingularAttribute attribute, - List relationalValueBindings, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - PropertyGeneration generation) { - final BasicAttributeBinding binding = new BasicAttributeBinding( - this, - attribute, - relationalValueBindings, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext, - generation - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public AggregatedCompositeAttributeBinding makeAggregatedCompositeAttributeBinding( - SingularAttribute attribute, - SingularAttribute parentReferenceAttribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext) { - final AggregatedCompositeAttributeBinding binding = new AggregatedCompositeAttributeBinding( - this, - attribute, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext, - parentReferenceAttribute - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - public NonAggregatedCompositeAttributeBinding makeVirtualCompositeAttributeBinding( + public CompositeAttributeBinding makeVirtualCompositeAttributeBinding( SingularAttribute syntheticAttribute, - List subAttributeBindings, - MetaAttributeContext metaAttributeContext) { + MetaAttributeContext metaAttributeContext, + List idAttributeBindings) { if ( !syntheticAttribute.isSynthetic() ) { throw new AssertionFailure( "Illegal attempt to create synthetic attribute binding from non-synthetic attribute reference" ); } - final NonAggregatedCompositeAttributeBinding binding = new NonAggregatedCompositeAttributeBinding( - this, - syntheticAttribute, - PropertyAccessorFactory.EMBEDDED_ACCESSOR_NAME, - SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, - metaAttributeContext, - subAttributeBindings - ); - registerAttributeBinding( syntheticAttribute.getName(), binding ); + // TODO: make sure all attributes are singular + final CompositeAttributeBinding binding = + CompositeAttributeBinding.createNonAggregatedCompositeAttributeBinding( + this, + syntheticAttribute, + PropertyAccessorFactory.EMBEDDED_ACCESSOR_NAME, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, + metaAttributeContext, + idAttributeBindings + ); + registerAttributeBinding( binding ); return binding; } @@ -573,164 +522,10 @@ public class EntityBinding implements MutableAttributeBindingContainer { pluralAttributeBinding ); - registerAttributeBinding( syntheticAttribute.getName(), binding ); + registerAttributeBinding( binding ); return binding; } - @Override - public ManyToOneAttributeBinding makeManyToOneAttributeBinding( - SingularAttribute attribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - EntityBinding referencedEntityBinding, - SingularAttributeBinding referencedAttributeBinding, - List valueBindings) { - final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( - this, - attribute, - propertyAccessorName, - includedInOptimisticLocking, - lazy, - naturalIdMutability, - metaAttributeContext, - referencedEntityBinding, - referencedAttributeBinding, - valueBindings - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public BagBinding makeBagAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext) { - Helper.checkPluralAttributeNature( attribute, PluralAttribute.Nature.BAG ); - final BagBinding binding = new BagBinding( - this, - attribute, - nature, - referencedAttributeBinding, - propertyAccessorName, - includedInOptimisticLocking, - metaAttributeContext - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public ListBinding makeListAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext, - int base) { - Helper.checkPluralAttributeNature( attribute, PluralAttribute.Nature.LIST ); - final ListBinding binding = new ListBinding( - this, - attribute, - nature, - referencedAttributeBinding, - propertyAccessorName, - includedInOptimisticLocking, - metaAttributeContext, - base - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public MapBinding makeMapAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature elementNature, - PluralAttributeIndexBinding.Nature indexNature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext) { - Helper.checkPluralAttributeNature( attribute, PluralAttribute.Nature.MAP ); - final MapBinding binding = new MapBinding( - this, - attribute, - elementNature, - indexNature, - referencedAttributeBinding, - propertyAccessorName, - includedInOptimisticLocking, - metaAttributeContext - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public SetBinding makeSetAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext) { - Helper.checkPluralAttributeNature( attribute, PluralAttribute.Nature.SET ); - final SetBinding binding = new SetBinding( - this, - attribute, - nature, - referencedAttributeBinding, - propertyAccessorName, - includedInOptimisticLocking, - metaAttributeContext - ); - registerAttributeBinding( attribute.getName(), binding ); - return binding; - } - - @Override - public AttributeBinding locateAttributeBinding(String name) { - return attributeBindingMap.get( name ); - } - - @Override - public AttributeBinding locateAttributeBinding(List values) { - for ( AttributeBinding attributeBinding : attributeBindingMap.values() ) { - if ( !SingularAttributeBinding.class.isInstance( attributeBinding ) ) { - continue; - } - SingularAttributeBinding basicAttributeBinding = (SingularAttributeBinding) attributeBinding; - - List attributeValues = new ArrayList(); - for ( RelationalValueBinding relationalBinding : basicAttributeBinding.getRelationalValueBindings() ) { - attributeValues.add( relationalBinding.getValue() ); - } - - if ( attributeValues.equals( values ) ) { - return attributeBinding; - } - } - return null; - } - - @Override - public Iterable attributeBindings() { - return attributeBindingMap.values(); - } - - @Override - public int attributeBindingSpan() { - return attributeBindingMap.size(); - } - /** * Gets the number of attribute bindings defined on this class, including the * identifier attribute binding and attribute bindings defined diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityIdentifier.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityIdentifier.java index 38106e9156..333df48107 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityIdentifier.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityIdentifier.java @@ -80,7 +80,7 @@ public class EntityIdentifier { } public void prepareAsAggregatedCompositeIdentifier( - SingularNonAssociationAttributeBinding attributeBinding, + CompositeAttributeBinding attributeBinding, IdGenerator idGenerator, String unsavedValue) { ensureNotBound(); @@ -89,7 +89,7 @@ public class EntityIdentifier { } public void prepareAsNonAggregatedCompositeIdentifier( - NonAggregatedCompositeAttributeBinding compositeAttributeBinding, + CompositeAttributeBinding compositeAttributeBinding, IdGenerator idGenerator, String unsavedValue, Class externalAggregatingClass, @@ -319,10 +319,18 @@ public class EntityIdentifier { private class AggregatedComponentIdentifierBindingImpl extends EntityIdentifierBinding { AggregatedComponentIdentifierBindingImpl( - SingularNonAssociationAttributeBinding identifierAttributeBinding, + CompositeAttributeBinding identifierAttributeBinding, IdGenerator idGenerator, String unsavedValue) { super( AGGREGATED_COMPOSITE, identifierAttributeBinding, idGenerator, unsavedValue ); + if ( ! identifierAttributeBinding.isAggregated() ) { + throw new IllegalArgumentException( + String.format( + "identifierAttributeBinding must be an aggregated CompositeAttributeBinding: %s", + identifierAttributeBinding.getAttribute().getName() + ) + ); + } } public IdentifierGenerator createIdentifierGenerator( @@ -354,12 +362,20 @@ public class EntityIdentifier { private final String externalAggregatingPropertyAccessorName; NonAggregatedCompositeIdentifierBindingImpl( - NonAggregatedCompositeAttributeBinding identifierAttributeBinding, + CompositeAttributeBinding identifierAttributeBinding, IdGenerator idGenerator, String unsavedValue, Class externalAggregatingClass, String externalAggregatingPropertyAccessorName) { super( NON_AGGREGATED_COMPOSITE, identifierAttributeBinding, idGenerator, unsavedValue ); + if ( identifierAttributeBinding.isAggregated() ) { + throw new IllegalArgumentException( + String.format( + "identifierAttributeBinding must be a non-aggregated CompositeAttributeBinding: %s", + identifierAttributeBinding.getAttribute().getName() + ) + ); + } this.externalAggregatingClass = externalAggregatingClass; this.externalAggregatingPropertyAccessorName = externalAggregatingPropertyAccessorName; if ( identifierAttributeBinding.attributeBindingSpan() == 0 ) { @@ -389,8 +405,8 @@ public class EntityIdentifier { } } - private NonAggregatedCompositeAttributeBinding getNonAggregatedCompositeAttributeBinding() { - return (NonAggregatedCompositeAttributeBinding) getAttributeBinding(); + private CompositeAttributeBinding getNonAggregatedCompositeAttributeBinding() { + return (CompositeAttributeBinding) getAttributeBinding(); } public boolean isIdentifierAttributeBinding(AttributeBinding attributeBinding) { for ( AttributeBinding idAttributeBindings : getNonAggregatedCompositeAttributeBinding().attributeBindings() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java index 392df13f64..f3593c7f5f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java @@ -122,24 +122,8 @@ public class ManyToOneAttributeBinding } @Override - public void setCascadeStyles(Iterable cascadeStyles) { - List cascadeStyleList = new ArrayList(); - for ( CascadeStyle style : cascadeStyles ) { - if ( style != CascadeStyles.NONE ) { - cascadeStyleList.add( style ); - } - } - if ( cascadeStyleList.isEmpty() ) { - cascadeStyle = CascadeStyles.NONE; - } - else if ( cascadeStyleList.size() == 1 ) { - cascadeStyle = cascadeStyleList.get( 0 ); - } - else { - cascadeStyle = new CascadeStyles.MultipleCascadeStyle( - cascadeStyleList.toArray( new CascadeStyle[cascadeStyleList.size()] ) - ); - } + public void setCascadeStyle(CascadeStyle cascadeStyle) { + this.cascadeStyle = cascadeStyle; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MutableAttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MutableAttributeBindingContainer.java deleted file mode 100644 index da627b9b09..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/MutableAttributeBindingContainer.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2012, 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.spi.binding; - -import java.util.List; - -import org.hibernate.mapping.PropertyGeneration; -import org.hibernate.metamodel.spi.domain.PluralAttribute; -import org.hibernate.metamodel.spi.domain.SingularAttribute; -import org.hibernate.metamodel.spi.source.MetaAttributeContext; - -/** - * @author Gail Badner - */ -public interface MutableAttributeBindingContainer extends AttributeBindingContainer { - - /** - * Factory method for basic attribute bindings. - * - * @param attribute The attribute for which to make a binding. - * @param relationalValueBindings - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param lazy - * @param metaAttributeContext - * @param generation - * - * @return The attribute binding instance. - */ - public BasicAttributeBinding makeBasicAttributeBinding( - SingularAttribute attribute, - List relationalValueBindings, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - PropertyGeneration generation); - - /** - * Factory method for component attribute bindings. - * - * @param attribute The attribute for which to make a binding. - * @param parentReferenceAttribute - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param lazy - * @param metaAttributeContext - * - * @return The attribute binding instance. - */ - public AggregatedCompositeAttributeBinding makeAggregatedCompositeAttributeBinding( - SingularAttribute attribute, - SingularAttribute parentReferenceAttribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext); - - /** - * Factory method for many-to-one attribute bindings. - * - * - * @param attribute The attribute for which to make a binding. - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param lazy - * @param metaAttributeContext - * @param referencedEntityBinding - * @param referencedAttributeBinding - * @param valueBindings - * - * @return The attribute binding instance. - */ - public ManyToOneAttributeBinding makeManyToOneAttributeBinding( - SingularAttribute attribute, - String propertyAccessorName, - boolean includedInOptimisticLocking, - boolean lazy, - SingularAttributeBinding.NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - EntityBinding referencedEntityBinding, - SingularAttributeBinding referencedAttributeBinding, - List valueBindings); - - /** - * Factory method for bag attribute bindings. - * - * - * @param attribute The attribute for which to make a binding. - * @param nature The nature of the collection elements. - * @param referencedAttributeBinding - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param metaAttributeContext - * - * @return The attribute binding instance. - */ - public BagBinding makeBagAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext); - - /** - * Factory method for list attribute bindings. - * - * - * @param attribute The attribute for which to make a binding. - * @param nature The nature of the collection elements. - * @param referencedAttributeBinding - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param metaAttributeContext - * @param base - * - * @return The attribute binding instance. - */ - public ListBinding makeListAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext, - int base); - - /** - * Factory method for map attribute bindings. - * - * - * @param attribute The attribute for which to make a binding. - * @param elementNature The nature of the collection elements. - * @param indexNature The nature of the collection indexes. - * @param referencedAttributeBinding - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param metaAttributeContext - * - * @return The attribute binding instance. - */ - public MapBinding makeMapAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature elementNature, - PluralAttributeIndexBinding.Nature indexNature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext); - - /** - * Factory method for set attribute bindings. - * - * - * @param attribute The attribute for which to make a binding. - * @param nature The nature of the collection elements. - * @param referencedAttributeBinding - * @param propertyAccessorName - * @param includedInOptimisticLocking - * @param metaAttributeContext - * - * @return The attribute binding instance. - */ - public SetBinding makeSetAttributeBinding( - PluralAttribute attribute, - PluralAttributeElementBinding.Nature nature, - SingularAttributeBinding referencedAttributeBinding, - String propertyAccessorName, - boolean includedInOptimisticLocking, - MetaAttributeContext metaAttributeContext); -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/NonAggregatedCompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/NonAggregatedCompositeAttributeBinding.java deleted file mode 100644 index cb5894de3d..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/NonAggregatedCompositeAttributeBinding.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2012, 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.spi.binding; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.hibernate.metamodel.spi.domain.AttributeContainer; -import org.hibernate.metamodel.spi.domain.SingularAttribute; -import org.hibernate.metamodel.spi.source.MetaAttributeContext; - -/** - * A composite attribute binding that contains an immutable tuple - * of attribute bindings that are mapped directly to the - * attribute binding's container. In other words, the tuple cannot - * be mapped to a single entity attribute. - * - * @todo should this be named something like TupleAttributebinding instead? - * - * @author Gail Badner - */ -public class NonAggregatedCompositeAttributeBinding extends AbstractCompositeAttributeBinding { - private final Map attributeBindingMap; - - public NonAggregatedCompositeAttributeBinding( - AttributeBindingContainer container, - SingularAttribute attribute, - String propertyAccessorName, - NaturalIdMutability naturalIdMutability, - MetaAttributeContext metaAttributeContext, - List subAttributeBindings) { - super( - container, - attribute, - propertyAccessorName, - false, - false, - naturalIdMutability, - metaAttributeContext - ); - if ( !AttributeContainer.class.isInstance( attribute.getSingularAttributeType() ) || - attribute.getSingularAttributeType().isAggregate() ) { - throw new IllegalArgumentException( - "Expected the attribute type to be an non-component attribute container" - ); - } - Map map = new LinkedHashMap(); - for ( SingularAttributeBinding attributeBinding : subAttributeBindings ) { - map.put( attributeBinding.getAttribute().getName(), attributeBinding ); - } - attributeBindingMap = Collections.unmodifiableMap( map ); - } - - @Override - public boolean isAggregated() { - return false; - } - - @Override - protected Map attributeBindingMapInternal() { - return attributeBindingMap; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeAssociationElementBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeAssociationElementBinding.java index 1cca832cd0..dd58aa8f64 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeAssociationElementBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeAssociationElementBinding.java @@ -30,5 +30,4 @@ package org.hibernate.metamodel.spi.binding; */ public interface PluralAttributeAssociationElementBinding extends PluralAttributeElementBinding, Cascadeable { - public boolean isOrphanDeleteEnabled(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeElementBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeElementBinding.java index 7562da757a..2f48d8f1c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeElementBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeElementBinding.java @@ -70,11 +70,11 @@ public interface PluralAttributeElementBinding { /** * The collection elements are basic, simple values. */ - BASIC( false ), + BASIC( false, false ), /** * The collection elements are compositions. */ - COMPONENT( false ), + AGGREGATE( false, true ), /** * The collection elements represent entity's in a one-to-many association. */ @@ -89,17 +89,23 @@ public interface PluralAttributeElementBinding { MANY_TO_ANY; private final boolean isAssociation; + private final boolean isCascadeable; private Nature() { - this( true ); + this( true, true ); } - private Nature(boolean association) { + private Nature(boolean association, boolean cascadeable) { this.isAssociation = association; + this.isCascadeable = cascadeable; } public boolean isAssociation() { return isAssociation; } + + public boolean isCascadeable() { + return isCascadeable; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeIndexBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeIndexBinding.java index 851308119f..136b5020d3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeIndexBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/PluralAttributeIndexBinding.java @@ -53,7 +53,7 @@ public interface PluralAttributeIndexBinding { /** * The map key is an aggregated composite */ - AGGREGATION, + AGGREGATE, /** * The map key is an association identified by a column(s) on the collection table. */ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/domain/TypeNature.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/domain/TypeNature.java index 2550d2bfa4..21ce86494e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/domain/TypeNature.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/domain/TypeNature.java @@ -32,7 +32,7 @@ package org.hibernate.metamodel.spi.domain; */ public enum TypeNature { BASIC( "basic" ), - AGGREGATION( "aggregation" ), + AGGREGATE( "aggregate" ), ENTITY( "entity" ), SUPERCLASS( "superclass" ), NON_ENTITY( "non-entity" ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/CompositePluralAttributeElementSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/CompositePluralAttributeElementSource.java index 55301fb4ba..d1c93a5b9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/CompositePluralAttributeElementSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/CompositePluralAttributeElementSource.java @@ -28,7 +28,8 @@ import org.hibernate.internal.util.ValueHolder; /** * @author Steve Ebersole */ -public interface CompositePluralAttributeElementSource extends PluralAttributeElementSource, AttributeSourceContainer { +public interface CompositePluralAttributeElementSource + extends PluralAttributeElementSource, AttributeSourceContainer, CascadeStyleSource { public String getClassName(); public ValueHolder> getClassReference(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeElementSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeElementSource.java index fdf88397b8..c5ac9111b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeElementSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/PluralAttributeElementSource.java @@ -36,7 +36,7 @@ public interface PluralAttributeElementSource { */ enum Nature { BASIC, - COMPONENT, + AGGREGATE, ONE_TO_MANY, MANY_TO_MANY, MANY_TO_ANY diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java index 929f6a5fbd..40b5ad6159 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java @@ -75,6 +75,9 @@ public interface SingularAttributeSource extends AttributeSource, RelationalValu */ enum Nature { BASIC, + // TODO: COMPOSITE should be changed to AGGREGATE + // when non-aggregated composite IDs are no longer + // modelled as an AttributeBinding COMPOSITE, MANY_TO_ONE, ONE_TO_ONE, diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 17b7cc38b4..da45f30c0f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -80,12 +80,11 @@ import org.hibernate.mapping.List; import org.hibernate.mapping.Selectable; import org.hibernate.mapping.Table; import org.hibernate.metadata.CollectionMetadata; -import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; +import org.hibernate.metamodel.spi.binding.Cascadeable; import org.hibernate.metamodel.spi.binding.CustomSQL; import org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.ListBinding; -import org.hibernate.metamodel.spi.binding.PluralAttributeAssociationElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding; import org.hibernate.metamodel.spi.binding.RelationalValueBinding; @@ -728,8 +727,8 @@ public abstract class AbstractCollectionPersister null; hasOrphanDelete = - collection.getPluralAttributeElementBinding().getNature().isAssociation() && - ( ( PluralAttributeAssociationElementBinding ) collection.getPluralAttributeElementBinding() ).isOrphanDeleteEnabled(); + collection.getPluralAttributeElementBinding() instanceof Cascadeable && + ( (Cascadeable) collection.getPluralAttributeElementBinding() ).getCascadeStyle().hasOrphanDelete(); int batch = collection.getBatchSize(); if ( batch == -1 ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java index 83627b1172..fa010c168a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java @@ -52,7 +52,6 @@ import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding; import org.hibernate.metamodel.spi.binding.PluralAttributeKeyBinding; -import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.relational.ForeignKey; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.OuterJoinLoadable; @@ -112,8 +111,6 @@ public class OneToManyPersister extends AbstractCollectionPersister { final PluralAttributeKeyBinding keyBinding = collection.getPluralAttributeKeyBinding(); cascadeDeleteEnabled = keyBinding.getForeignKey().getDeleteRule() == ForeignKey.ReferentialAction.CASCADE && factory.getDialect().supportsCascadeDelete();; - final SingularAttributeBinding referencedAttributeBinding = - keyBinding.getReferencedAttributeBinding(); keyIsNullable = keyBinding.isNullable(); keyIsUpdateable = keyBinding.isUpdatable(); } 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 4977266eaf..7833e682ae 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 @@ -101,6 +101,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; import org.hibernate.metadata.ClassMetadata; +import org.hibernate.metamodel.spi.binding.Cascadeable; import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; @@ -1074,14 +1075,14 @@ public abstract class AbstractEntityPersister propFormulaNumbers.add( formnos ); CascadeStyle cascadeStyle = null; - if ( attributeBinding.isAssociation() ) { + if ( attributeBinding.isCascadeable() ) { if ( attributeBinding.getAttribute().isSingular() ) { - cascadeStyle = ( ( SingularAssociationAttributeBinding) attributeBinding ).getCascadeStyle(); + cascadeStyle = ( (Cascadeable) attributeBinding ).getCascadeStyle(); } else { PluralAttributeElementBinding pluralAttributeElementBinding = ( (PluralAttributeBinding) attributeBinding ).getPluralAttributeElementBinding(); - cascadeStyle = ( (PluralAttributeAssociationElementBinding) pluralAttributeElementBinding).getCascadeStyle(); + cascadeStyle = ( (Cascadeable) pluralAttributeElementBinding).getCascadeStyle(); } } if ( cascadeStyle == null ) { 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 40c1ad3d82..fcf48843cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -40,13 +40,13 @@ import org.hibernate.mapping.KeyValue; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.Cascadeable; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.BackRefAttributeBinding; import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.EntityBinding; -import org.hibernate.metamodel.spi.binding.NonAggregatedCompositeAttributeBinding; -import org.hibernate.metamodel.spi.binding.PluralAttributeAssociationElementBinding; import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.property.Getter; @@ -133,7 +133,7 @@ public class PropertyFactory { final Type type; if ( mappedEntity.getHierarchyDetails().getEntityIdentifier().isIdentifierMapper() ) { type = sessionFactory.getTypeResolver().getTypeFactory().component( - new ComponentMetamodel( (NonAggregatedCompositeAttributeBinding) attributeBinding, true, true ) + new ComponentMetamodel( ( (CompositeAttributeBinding) attributeBinding ), true, true ) ); } else { @@ -229,8 +229,8 @@ public class PropertyFactory { boolean lazy = lazyAvailable && property.isLazy(); - final CascadeStyle cascadeStyle = property.isAssociation() - ? ( (SingularAssociationAttributeBinding) property ).getCascadeStyle() + final CascadeStyle cascadeStyle = property.isCascadeable() + ? ( (Cascadeable) property ).getCascadeStyle() : CascadeStyles.NONE; return new VersionProperty( @@ -313,8 +313,8 @@ public class PropertyFactory { if ( property.getAttribute().isSingular() ) { final SingularAttributeBinding singularAttributeBinding = ( SingularAttributeBinding ) property; - final CascadeStyle cascadeStyle = singularAttributeBinding.isAssociation() - ? ( (SingularAssociationAttributeBinding) singularAttributeBinding ).getCascadeStyle() + final CascadeStyle cascadeStyle = singularAttributeBinding.isCascadeable() + ? ( (Cascadeable) singularAttributeBinding ).getCascadeStyle() : CascadeStyles.NONE; final FetchMode fetchMode = singularAttributeBinding.isAssociation() ? ( (SingularAssociationAttributeBinding) singularAttributeBinding ).getFetchMode() @@ -342,9 +342,15 @@ public class PropertyFactory { } else { final AbstractPluralAttributeBinding pluralAttributeBinding = (AbstractPluralAttributeBinding) property; - final CascadeStyle cascadeStyle = pluralAttributeBinding.isAssociation() - ? ( (PluralAttributeAssociationElementBinding) pluralAttributeBinding.getPluralAttributeElementBinding() ).getCascadeStyle() - : CascadeStyles.NONE; + final CascadeStyle cascadeStyle; + if ( pluralAttributeBinding.isCascadeable() ) { + final Cascadeable elementBinding = + (Cascadeable) pluralAttributeBinding.getPluralAttributeElementBinding(); + cascadeStyle = elementBinding.getCascadeStyle(); + } + else { + cascadeStyle = CascadeStyles.NONE; + } final FetchMode fetchMode = pluralAttributeBinding.isAssociation() ? pluralAttributeBinding.getFetchMode() : FetchMode.DEFAULT; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java index a14399b249..d68f2206a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java @@ -32,7 +32,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.metamodel.spi.binding.AttributeBinding; -import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; import org.hibernate.metamodel.spi.binding.EntityIdentifier; import org.hibernate.property.Getter; import org.hibernate.property.Setter; @@ -81,10 +81,10 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { // so it can provide the information needed to create getters and setters // for an identifier mapper. protected AbstractComponentTuplizer( - CompositeAttributeBinding compositeAttributeBinding, + CompositeAttributeBindingContainer compositeAttributeBindingContainer, boolean isIdentifierMapper ) { - propertySpan = compositeAttributeBinding.attributeBindingSpan(); + propertySpan = compositeAttributeBindingContainer.attributeBindingSpan(); getters = new Getter[propertySpan]; setters = new Setter[propertySpan]; @@ -97,10 +97,10 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { // HACK ALERT: when isIdentifierMapper is true, the entity identifier // must be completely bound when this method is called. final EntityMode entityMode = - compositeAttributeBinding.getContainer().seekEntityBinding().getHierarchyDetails().getEntityMode(); + compositeAttributeBindingContainer.seekEntityBinding().getHierarchyDetails().getEntityMode(); final EntityIdentifier entityIdentifier = - compositeAttributeBinding.seekEntityBinding().getHierarchyDetails().getEntityIdentifier(); - for ( AttributeBinding attributeBinding : compositeAttributeBinding.attributeBindings() ) { + compositeAttributeBindingContainer.seekEntityBinding().getHierarchyDetails().getEntityIdentifier(); + for ( AttributeBinding attributeBinding : compositeAttributeBindingContainer.attributeBindings() ) { getters[i] = PropertyFactory.getIdentifierMapperGetter( attributeBinding.getAttribute().getName(), entityIdentifier.getIdClassPropertyAccessorName(), @@ -119,7 +119,7 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { } } else { - for ( AttributeBinding attributeBinding : compositeAttributeBinding.attributeBindings() ) { + for ( AttributeBinding attributeBinding : compositeAttributeBindingContainer.attributeBindings() ) { getters[i] = PropertyFactory.getGetter( attributeBinding ); setters[i] = PropertyFactory.getSetter( attributeBinding ); if ( !attributeBinding.isBasicPropertyAccessor() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java index 01e0039d84..8359a2af07 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java @@ -33,7 +33,7 @@ import org.hibernate.HibernateException; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.metamodel.spi.binding.AttributeBinding; -import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; import org.hibernate.tuple.PropertyFactory; import org.hibernate.tuple.StandardProperty; @@ -84,7 +84,7 @@ public class ComponentMetamodel implements Serializable { } public ComponentMetamodel( - CompositeAttributeBinding component, + CompositeAttributeBindingContainer component, boolean isIdentifierAttributeBinding, boolean isIdentifierMapper) { this.isKey = isIdentifierAttributeBinding; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentTuplizerFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentTuplizerFactory.java index c18cdba380..14c7a3f1cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentTuplizerFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentTuplizerFactory.java @@ -32,7 +32,7 @@ import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.mapping.Component; -import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; /** * A registry allowing users to define the default {@link ComponentTuplizer} class to use per {@link EntityMode}. @@ -42,7 +42,7 @@ import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; public class ComponentTuplizerFactory implements Serializable { private static final Class[] COMPONENT_TUP_CTOR_SIG = new Class[] { Component.class }; private static final Class[] COMPONENT_TUP_CTOR_SIG_NEW = new Class[] { - CompositeAttributeBinding.class, + CompositeAttributeBindingContainer.class, boolean.class }; @@ -102,7 +102,7 @@ public class ComponentTuplizerFactory implements Serializable { @SuppressWarnings({ "unchecked" }) public ComponentTuplizer constructTuplizer( String tuplizerClassName, - CompositeAttributeBinding metadata, + CompositeAttributeBindingContainer metadata, boolean isIdentifierMapper) { try { Class tuplizerClass = ReflectHelper.classForName( tuplizerClassName ); @@ -146,7 +146,7 @@ public class ComponentTuplizerFactory implements Serializable { */ public ComponentTuplizer constructTuplizer( Class tuplizerClass, - CompositeAttributeBinding metadata, + CompositeAttributeBindingContainer metadata, boolean isIdentifierMapper) { Constructor constructor = getProperConstructor( tuplizerClass, COMPONENT_TUP_CTOR_SIG_NEW ); assert constructor != null : "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName() + "]"; @@ -191,7 +191,7 @@ public class ComponentTuplizerFactory implements Serializable { */ public ComponentTuplizer constructDefaultTuplizer( EntityMode entityMode, - CompositeAttributeBinding metadata, + CompositeAttributeBindingContainer metadata, boolean isIdentifierMapper) { Class tuplizerClass = defaultImplClassByMode.get( entityMode ); if ( tuplizerClass == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java index 33a79c5701..57a70c9d9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java @@ -36,8 +36,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; -import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer; import org.hibernate.metamodel.spi.binding.EntityIdentifier; import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.property.Getter; @@ -99,7 +98,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer { } public PojoComponentTuplizer( - CompositeAttributeBinding component, + CompositeAttributeBindingContainer component, boolean isIdentifierMapper) { super( component, isIdentifierMapper ); @@ -121,10 +120,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer { } final String parentPropertyName = - component.isAggregated() && - ( (AggregatedCompositeAttributeBinding) component ).getParentReference() != null ? - ( (AggregatedCompositeAttributeBinding) component ).getParentReference().getName() : - null; + component.getParentReference() == null ? null : component.getParentReference().getName(); if ( parentPropertyName == null ) { parentSetter = null; parentGetter = null; @@ -145,7 +141,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer { componentClass, getterNames, setterNames, propTypes ); } - instantiator = buildInstantiator( componentClass, component.getAttribute().isSynthetic(), optimizer ); + instantiator = buildInstantiator( componentClass, !component.isAggregated(), optimizer ); } public Class getMappedClass() { diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableBindingTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableBindingTest.java index ebe5da1ccb..3496a91ff1 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableBindingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableBindingTest.java @@ -35,9 +35,8 @@ import org.junit.Test; import org.hibernate.annotations.Parent; import org.hibernate.annotations.Target; -import org.hibernate.metamodel.spi.binding.AggregatedCompositeAttributeBinding; -import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding; +import org.hibernate.metamodel.spi.binding.BasicAttributeBinding; import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.testing.junit4.BaseAnnotationBindingTestCase; import org.hibernate.testing.junit4.Resources; @@ -332,7 +331,7 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase { final String componentName = "embedded"; assertNotNull( binding.locateAttributeBinding( componentName ) ); assertTrue( binding.locateAttributeBinding( componentName ) instanceof CompositeAttributeBinding ); - AggregatedCompositeAttributeBinding compositeBinding = (AggregatedCompositeAttributeBinding) binding.locateAttributeBinding( + CompositeAttributeBinding compositeBinding = (CompositeAttributeBinding) binding.locateAttributeBinding( componentName ); @@ -390,7 +389,9 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase { componentName ); - BasicAttributeBinding attribute = (BasicAttributeBinding) compositeBinding.locateAttributeBinding( "horsePower" ); + BasicAttributeBinding attribute = (BasicAttributeBinding) compositeBinding.locateAttributeBinding( + "horsePower" + ); assertTrue( attribute.getAttribute().isTypeResolved() ); assertEquals( "Wrong resolved type", diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/AbstractBasicBindingTests.java index 7c32d04bca..4d208aed0e 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/AbstractBasicBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/AbstractBasicBindingTests.java @@ -39,6 +39,7 @@ import org.hibernate.engine.spi.CascadeStyles; import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.internal.MetadataImpl; import org.hibernate.metamodel.spi.MetadataImplementor; +import org.hibernate.metamodel.spi.domain.Aggregate; import org.hibernate.metamodel.spi.domain.Attribute; import org.hibernate.metamodel.spi.domain.BasicType; import org.hibernate.metamodel.spi.domain.Entity; @@ -240,13 +241,13 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { assertRoot( metadata, entityBinding ); assertIdAndSimpleProperty( entityBinding ); - AggregatedCompositeAttributeBinding compositeAttributeBinding = - (AggregatedCompositeAttributeBinding) entityBinding.locateAttributeBinding( "simpleComponent" ); + CompositeAttributeBinding compositeAttributeBinding = + (CompositeAttributeBinding) entityBinding.locateAttributeBinding( "simpleComponent" ); assertNotNull( compositeAttributeBinding ); assertSame( compositeAttributeBinding.getAttribute().getSingularAttributeType(), compositeAttributeBinding.getAttributeContainer() ); assertEquals( SimpleEntityWithSimpleComponent.class.getName() + ".simpleComponent", compositeAttributeBinding.getPathBase() ); assertSame( entityBinding, compositeAttributeBinding.seekEntityBinding() ); - assertNotNull( compositeAttributeBinding.getComposite() ); + assertTrue( compositeAttributeBinding.getAttribute().getSingularAttributeType() instanceof Aggregate ); } public abstract void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources); diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetNonLazyTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetNonLazyTest.java index 216b9cd17e..d092d63349 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetNonLazyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetNonLazyTest.java @@ -31,7 +31,6 @@ import org.hibernate.testing.FailureExpectedWithNewMetamodel; /** * @author Gail Badner */ -@FailureExpectedWithNewMetamodel public class PersistentSetNonLazyTest extends PersistentSetTest { @Override public String[] getMappings() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetTest.java index ee606112d6..63bed90875 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/collection/set/PersistentSetTest.java @@ -45,7 +45,6 @@ import static org.junit.Assert.assertTrue; /** * @author Steve Ebersole */ -@FailureExpectedWithNewMetamodel public class PersistentSetTest extends BaseCoreFunctionalTestCase { @Override public String[] getMappings() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/compositeelement/CompositeElementTest.java b/hibernate-core/src/test/java/org/hibernate/test/compositeelement/CompositeElementTest.java index 4eaaafaf67..10101869b4 100755 --- a/hibernate-core/src/test/java/org/hibernate/test/compositeelement/CompositeElementTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/compositeelement/CompositeElementTest.java @@ -44,7 +44,6 @@ import static org.junit.Assert.assertEquals; /** * @author Gavin King */ -@FailureExpectedWithNewMetamodel public class CompositeElementTest extends BaseCoreFunctionalTestCase { @Override public String[] getMappings() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java b/hibernate-core/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java index 7548880cbc..e4ed4c18eb 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/event/collection/values/ValuesBagCollectionEventTest.java @@ -34,7 +34,6 @@ import org.hibernate.testing.FailureExpectedWithNewMetamodel; * * @author Gail Badner */ -@FailureExpectedWithNewMetamodel public class ValuesBagCollectionEventTest extends AbstractCollectionEventTest { @Override public String[] getMappings() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/mapcompelem/MapCompositeElementTest.java b/hibernate-core/src/test/java/org/hibernate/test/mapcompelem/MapCompositeElementTest.java index 1f450bb459..9160e5639e 100755 --- a/hibernate-core/src/test/java/org/hibernate/test/mapcompelem/MapCompositeElementTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/mapcompelem/MapCompositeElementTest.java @@ -39,7 +39,6 @@ import static org.junit.Assert.assertTrue; /** * @author Gavin King */ -@FailureExpectedWithNewMetamodel public class MapCompositeElementTest extends BaseCoreFunctionalTestCase { @Override public String[] getMappings() {