From 1b69d460b3e0ba296823ef228070760589b0b51c Mon Sep 17 00:00:00 2001 From: Strong Liu Date: Mon, 3 Sep 2012 21:16:22 +0800 Subject: [PATCH] HHH-7549 @OneToMany support --- .../hibernate/metamodel/internal/Binder.java | 30 ++++++++-------- .../PluralAttributeKeySourceImpl.java | 28 ++++++++++++--- .../attribute/AssociationAttribute.java | 18 ++-------- .../attribute/MappedAttribute.java | 28 +++++++++++---- .../attribute/PluralAssociationAttribute.java | 36 ++++++++++--------- 5 files changed, 82 insertions(+), 58 deletions(-) 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 04e89c3703..442c8f672a 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 @@ -52,8 +52,6 @@ import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.ValueHolder; import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; -import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource; -import org.hibernate.metamodel.internal.source.hbm.MapAttributeSource; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding; @@ -1002,11 +1000,12 @@ public class Binder { private AbstractPluralAttributeBinding bindListAttribute( final AttributeBindingContainer attributeBindingContainer, - final ListAttributeSource attributeSource, + final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() ); } + final int base = IndexedPluralAttributeSource.class.isInstance( attributeSource ) ? IndexedPluralAttributeSource.class.cast( attributeSource ).getIndexSource().base() : 0; return attributeBindingContainer.makeListAttributeBinding( attribute, pluralAttributeElementNature( attributeSource ), @@ -1014,7 +1013,7 @@ public class Binder { propertyAccessorName( attributeSource ), attributeSource.isIncludedInOptimisticLocking(), createMetaAttributeContext( attributeBindingContainer, attributeSource ), - attributeSource.getIndexSource().base() + base ); } @@ -1115,7 +1114,7 @@ public class Binder { private AbstractPluralAttributeBinding bindMapAttribute( final AttributeBindingContainer attributeBindingContainer, - final MapAttributeSource attributeSource, + final PluralAttributeSource attributeSource, PluralAttribute attribute ) { if ( attribute == null ) { attribute = attributeBindingContainer.getAttributeContainer().createMap( attributeSource.getName() ); @@ -1263,7 +1262,7 @@ public class Binder { case LIST: attributeBinding = bindListAttribute( attributeBindingContainer, - (ListAttributeSource) attributeSource, + attributeSource, attribute ); resolvedType = resolveListType( (ListBinding) attributeBinding ); @@ -1271,7 +1270,7 @@ public class Binder { case MAP: attributeBinding = bindMapAttribute( attributeBindingContainer, - (MapAttributeSource) attributeSource, + attributeSource, attribute ); resolvedType = resolveMapType( (MapBinding) attributeBinding ); @@ -1970,15 +1969,14 @@ public class Binder { return entityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding(); } - final String explicitName = resolutionDelegate.getReferencedAttributeName(); - final String referencedAttributeName; - if ( explicitName == null ) { - throw new NotYetImplementedException( "Annotation-style property-ref resolution not yet implemented" ); + AttributeBinding referencedAttributeBinding; + final String referencedAttributeName = resolutionDelegate.getReferencedAttributeName(); + if ( referencedAttributeName == null ) { + referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( resolutionDelegate.getJoinColumns( ) ); } else { - referencedAttributeName = explicitName; + referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName ); } - AttributeBinding referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName ); if ( referencedAttributeBinding == null ) { referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName ); @@ -1988,7 +1986,7 @@ public class Binder { + referencedAttributeBinding, bindingContexts.peek().getOrigin() ); } if ( !referencedAttributeBinding.getAttribute().isSingular() ) { - throw new MappingException( "Plural attribute key references a plural attribute; it must be plural: " + throw new MappingException( "Plural attribute key references a plural attribute; it must not be plural: " + referencedAttributeName, bindingContexts.peek().getOrigin() ); } return ( SingularAttributeBinding ) referencedAttributeBinding; @@ -2003,7 +2001,9 @@ public class Binder { } final String explicitName = resolutionDelegate.getReferencedAttributeName(); - return explicitName != null ? referencedEntityBinding.locateAttributeBinding( explicitName ) :referencedEntityBinding.locateAttributeBinding(resolutionDelegate.getJoinColumns( resolutionContext ) ); + return explicitName != null + ? referencedEntityBinding.locateAttributeBinding( explicitName ) + :referencedEntityBinding.locateAttributeBinding(resolutionDelegate.getJoinColumns( resolutionContext ) ); } private EntityBinding entityBinding( final String entityName ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeKeySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeKeySourceImpl.java index e4e0010e89..4f12a92c2d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeKeySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/PluralAttributeKeySourceImpl.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.List; import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.internal.source.annotations.attribute.Column; import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute; import org.hibernate.metamodel.spi.relational.ForeignKey; @@ -82,21 +83,38 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource { @Override public String getExplicitForeignKeyName() { - return null; + return attribute.getExplicitForeignKeyName(); } @Override public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() { - return null; //new JoinColumnResolutionDelegateImpl(); + + for ( Column joinColumn : attribute.getJoinColumnValues() ) { + if ( StringHelper.isNotEmpty( joinColumn.getReferencedColumnName() ) ) { + return new JoinColumnResolutionDelegateImpl( attribute ); + } + } + return null; } @Override public List relationalValueSources() { - // TODO - return Collections.emptyList(); + if(attribute.getJoinColumnValues().isEmpty())return Collections.emptyList(); + List result = new ArrayList( attribute.getJoinColumnValues().size() ); + for(Column joinColumn : attribute.getJoinColumnValues()){ + result.add( new ColumnSourceImpl( attribute, null, joinColumn ) ); + } + return result; } public static class JoinColumnResolutionDelegateImpl implements JoinColumnResolutionDelegate { + private final PluralAssociationAttribute attribute; + + public JoinColumnResolutionDelegateImpl(PluralAssociationAttribute attribute) { + this.attribute = attribute; + + } + @Override public List getJoinColumns(JoinColumnResolutionContext context) { return null; //To change body of implemented methods use File | Settings | File Templates. @@ -104,7 +122,7 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource { @Override public String getReferencedAttributeName() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java index 460406674d..0ac7d40d83 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java @@ -223,15 +223,8 @@ public class AssociationAttribute extends MappedAttribute { } protected boolean determineIsLazy(AnnotationInstance associationAnnotation) { - boolean lazy = false; - AnnotationValue fetchValue = associationAnnotation.value( "fetch" ); - if ( fetchValue != null ) { - FetchType fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() ); - if ( FetchType.LAZY.equals( fetchType ) ) { - lazy = true; - } - } - return lazy; + FetchType fetchType = JandexHelper.getEnumValue( associationAnnotation, "fetch", FetchType.class ); + return FetchType.LAZY == fetchType; } private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class referencedAttributeType) { @@ -310,12 +303,10 @@ public class AssociationAttribute extends MappedAttribute { } private String determineMapsId() { - String referencedIdAttributeName; AnnotationInstance mapsIdAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.MAPS_ID ); if ( mapsIdAnnotation == null ) { return null; } - if ( !( Nature.MANY_TO_ONE.equals( getNature() ) || Nature.MANY_TO_ONE .equals( getNature() ) ) ) { throw new MappingException( @@ -323,10 +314,7 @@ public class AssociationAttribute extends MappedAttribute { getContext().getOrigin() ); } - - referencedIdAttributeName = JandexHelper.getValue( mapsIdAnnotation, "value", String.class ); - - return referencedIdAttributeName; + return JandexHelper.getValue( mapsIdAnnotation, "value", String.class ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java index b9bf5f92dc..c42f1ea91a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java @@ -75,7 +75,9 @@ public abstract class MappedAttribute implements Comparable { * Defines the column values (relational values) for this property. A mapped property can refer to multiple * column values in case of components or join columns etc */ - private List columnValues; + private List columnValues = new ArrayList( ); + + private List joinColumnValues = new ArrayList( ); /** * Is this property an id property (or part thereof). @@ -152,6 +154,10 @@ public abstract class MappedAttribute implements Comparable { return columnValues; } + public List getJoinColumnValues(){ + return joinColumnValues; + } + public boolean isId() { return isId; } @@ -228,14 +234,15 @@ public abstract class MappedAttribute implements Comparable { } private void checkColumnAnnotations(Map> annotations) { - columnValues = new ArrayList(); - - // single @Column + // single @Column AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN ); if ( columnAnnotation != null ) { + if ( getNature() == Nature.MANY_TO_ONE || getNature() == Nature.ONE_TO_ONE) { + throw getContext().makeMappingException( "@Column(s) not allowed on a "+ getNature() +" property: " +getContext().getOrigin().getName() +"."+ name ); + } columnValues.add( new Column( columnAnnotation ) ); } @@ -245,7 +252,7 @@ public abstract class MappedAttribute implements Comparable { JPADotNames.JOIN_COLUMN ); if ( joinColumnAnnotation != null ) { - columnValues.add( new Column( joinColumnAnnotation ) ); + joinColumnValues.add( new Column( joinColumnAnnotation ) ); } // @org.hibernate.annotations.Columns @@ -254,6 +261,9 @@ public abstract class MappedAttribute implements Comparable { HibernateDotNames.COLUMNS ); if ( columnsAnnotation != null ) { + if ( getNature() == Nature.MANY_TO_ONE || getNature() == Nature.ONE_TO_ONE) { + throw getContext().makeMappingException( "@Column(s) not allowed on a "+ getNature() +" property: " +getContext().getOrigin().getName() +"."+ name ); + } List columnsList = Arrays.asList( JandexHelper.getValue( columnsAnnotation, "value", AnnotationInstance[].class ) ); @@ -272,7 +282,7 @@ public abstract class MappedAttribute implements Comparable { JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class ) ); for ( AnnotationInstance annotation : columnsList ) { - columnValues.add( new Column( annotation ) ); + joinColumnValues.add( new Column( annotation ) ); } } } @@ -311,6 +321,12 @@ public abstract class MappedAttribute implements Comparable { public DotName getAnnotationDotName() { return annotationDotName; } + + @Override + public String toString() { + return "Nature{" +annotationDotName.toString()+ + '}'; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java index 3535d3fab5..e8230cb344 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/PluralAssociationAttribute.java @@ -69,6 +69,7 @@ public class PluralAssociationAttribute extends AssociationAttribute { private final boolean isIndexed; // Used for the non-owning side of a ManyToMany relationship private final String inverseForeignKeyName; + private final String explicitForeignKeyName; private LazyCollectionOption lazyOption; @@ -103,6 +104,9 @@ public class PluralAssociationAttribute extends AssociationAttribute { public String getInverseForeignKeyName() { return inverseForeignKeyName; } + public String getExplicitForeignKeyName(){ + return explicitForeignKeyName; + } public Caching getCaching() { return caching; @@ -168,7 +172,21 @@ public class PluralAssociationAttribute extends AssociationAttribute { this.entityClassInfo = entityClassInfo; this.whereClause = determineWereClause(); this.orderBy = determineOrderBy(); - this.inverseForeignKeyName = determineInverseForeignKeyName(); + + AnnotationInstance foreignKey = JandexHelper.getSingleAnnotation( + annotations(), + HibernateDotNames.FOREIGN_KEY + ); + if ( foreignKey != null ) { + explicitForeignKeyName = JandexHelper.getValue( foreignKey, "name", String.class ); + String temp = JandexHelper.getValue( foreignKey, "inverseName", String.class ); + inverseForeignKeyName = StringHelper.isNotEmpty( temp ) ? temp : null; + } + else { + explicitForeignKeyName = null; + inverseForeignKeyName = null; + } + this.caching = determineCachingSettings(); this.isExtraLazy = lazyOption == LazyCollectionOption.EXTRA; this.customPersister = determineCustomPersister(); @@ -250,22 +268,6 @@ public class PluralAssociationAttribute extends AssociationAttribute { } return entityPersisterClass; } - - private String determineInverseForeignKeyName() { - String foreignKeyName = null; - - AnnotationInstance foreignKey = JandexHelper.getSingleAnnotation( - annotations(), - HibernateDotNames.FOREIGN_KEY - ); - if ( foreignKey != null && - StringHelper.isNotEmpty( JandexHelper.getValue( foreignKey, "inverseName", String.class ) ) ) { - foreignKeyName = JandexHelper.getValue( foreignKey, "inverseName", String.class ); - } - - return foreignKeyName; - } - @Override protected boolean determineIsLazy(AnnotationInstance associationAnnotation) { boolean lazy = super.determineIsLazy( associationAnnotation );