HHH-7549 @OneToMany support

This commit is contained in:
Strong Liu 2012-09-03 21:16:22 +08:00
parent 550f19f3da
commit 1b69d460b3
5 changed files with 82 additions and 58 deletions

View File

@ -52,8 +52,6 @@ import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.ValueHolder;
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; 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.MetadataImplementor;
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
@ -1002,11 +1000,12 @@ public class Binder {
private AbstractPluralAttributeBinding bindListAttribute( private AbstractPluralAttributeBinding bindListAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final ListAttributeSource attributeSource, final PluralAttributeSource attributeSource,
PluralAttribute attribute ) { PluralAttribute attribute ) {
if ( attribute == null ) { if ( attribute == null ) {
attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() ); attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() );
} }
final int base = IndexedPluralAttributeSource.class.isInstance( attributeSource ) ? IndexedPluralAttributeSource.class.cast( attributeSource ).getIndexSource().base() : 0;
return attributeBindingContainer.makeListAttributeBinding( return attributeBindingContainer.makeListAttributeBinding(
attribute, attribute,
pluralAttributeElementNature( attributeSource ), pluralAttributeElementNature( attributeSource ),
@ -1014,7 +1013,7 @@ public class Binder {
propertyAccessorName( attributeSource ), propertyAccessorName( attributeSource ),
attributeSource.isIncludedInOptimisticLocking(), attributeSource.isIncludedInOptimisticLocking(),
createMetaAttributeContext( attributeBindingContainer, attributeSource ), createMetaAttributeContext( attributeBindingContainer, attributeSource ),
attributeSource.getIndexSource().base() base
); );
} }
@ -1115,7 +1114,7 @@ public class Binder {
private AbstractPluralAttributeBinding bindMapAttribute( private AbstractPluralAttributeBinding bindMapAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final MapAttributeSource attributeSource, final PluralAttributeSource attributeSource,
PluralAttribute attribute ) { PluralAttribute attribute ) {
if ( attribute == null ) { if ( attribute == null ) {
attribute = attributeBindingContainer.getAttributeContainer().createMap( attributeSource.getName() ); attribute = attributeBindingContainer.getAttributeContainer().createMap( attributeSource.getName() );
@ -1263,7 +1262,7 @@ public class Binder {
case LIST: case LIST:
attributeBinding = bindListAttribute( attributeBinding = bindListAttribute(
attributeBindingContainer, attributeBindingContainer,
(ListAttributeSource) attributeSource, attributeSource,
attribute attribute
); );
resolvedType = resolveListType( (ListBinding) attributeBinding ); resolvedType = resolveListType( (ListBinding) attributeBinding );
@ -1271,7 +1270,7 @@ public class Binder {
case MAP: case MAP:
attributeBinding = bindMapAttribute( attributeBinding = bindMapAttribute(
attributeBindingContainer, attributeBindingContainer,
(MapAttributeSource) attributeSource, attributeSource,
attribute attribute
); );
resolvedType = resolveMapType( (MapBinding) attributeBinding ); resolvedType = resolveMapType( (MapBinding) attributeBinding );
@ -1970,15 +1969,14 @@ public class Binder {
return entityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding(); return entityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
} }
final String explicitName = resolutionDelegate.getReferencedAttributeName(); AttributeBinding referencedAttributeBinding;
final String referencedAttributeName; final String referencedAttributeName = resolutionDelegate.getReferencedAttributeName();
if ( explicitName == null ) { if ( referencedAttributeName == null ) {
throw new NotYetImplementedException( "Annotation-style property-ref resolution not yet implemented" ); referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( resolutionDelegate.getJoinColumns( ) );
} else { } else {
referencedAttributeName = explicitName; referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName );
} }
AttributeBinding referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName );
if ( referencedAttributeBinding == null ) { if ( referencedAttributeBinding == null ) {
referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName ); referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName );
@ -1988,7 +1986,7 @@ public class Binder {
+ referencedAttributeBinding, bindingContexts.peek().getOrigin() ); + referencedAttributeBinding, bindingContexts.peek().getOrigin() );
} }
if ( !referencedAttributeBinding.getAttribute().isSingular() ) { 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() ); + referencedAttributeName, bindingContexts.peek().getOrigin() );
} }
return ( SingularAttributeBinding ) referencedAttributeBinding; return ( SingularAttributeBinding ) referencedAttributeBinding;
@ -2003,7 +2001,9 @@ public class Binder {
} }
final String explicitName = resolutionDelegate.getReferencedAttributeName(); 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 ) { private EntityBinding entityBinding( final String entityName ) {

View File

@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.hibernate.annotations.OnDeleteAction; 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.Column;
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
import org.hibernate.metamodel.spi.relational.ForeignKey; import org.hibernate.metamodel.spi.relational.ForeignKey;
@ -82,21 +83,38 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
@Override @Override
public String getExplicitForeignKeyName() { public String getExplicitForeignKeyName() {
return null; return attribute.getExplicitForeignKeyName();
} }
@Override @Override
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() { public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
return null; //new JoinColumnResolutionDelegateImpl();
for ( Column joinColumn : attribute.getJoinColumnValues() ) {
if ( StringHelper.isNotEmpty( joinColumn.getReferencedColumnName() ) ) {
return new JoinColumnResolutionDelegateImpl( attribute );
}
}
return null;
} }
@Override @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
// TODO if(attribute.getJoinColumnValues().isEmpty())return Collections.emptyList();
return Collections.emptyList(); List<RelationalValueSource> result = new ArrayList<RelationalValueSource>( attribute.getJoinColumnValues().size() );
for(Column joinColumn : attribute.getJoinColumnValues()){
result.add( new ColumnSourceImpl( attribute, null, joinColumn ) );
}
return result;
} }
public static class JoinColumnResolutionDelegateImpl implements JoinColumnResolutionDelegate { public static class JoinColumnResolutionDelegateImpl implements JoinColumnResolutionDelegate {
private final PluralAssociationAttribute attribute;
public JoinColumnResolutionDelegateImpl(PluralAssociationAttribute attribute) {
this.attribute = attribute;
}
@Override @Override
public List<Value> getJoinColumns(JoinColumnResolutionContext context) { public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
return null; //To change body of implemented methods use File | Settings | File Templates. return null; //To change body of implemented methods use File | Settings | File Templates.
@ -104,7 +122,7 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
@Override @Override
public String getReferencedAttributeName() { public String getReferencedAttributeName() {
return null; //To change body of implemented methods use File | Settings | File Templates. return null;
} }
} }
} }

View File

@ -223,15 +223,8 @@ public class AssociationAttribute extends MappedAttribute {
} }
protected boolean determineIsLazy(AnnotationInstance associationAnnotation) { protected boolean determineIsLazy(AnnotationInstance associationAnnotation) {
boolean lazy = false; FetchType fetchType = JandexHelper.getEnumValue( associationAnnotation, "fetch", FetchType.class );
AnnotationValue fetchValue = associationAnnotation.value( "fetch" ); return FetchType.LAZY == fetchType;
if ( fetchValue != null ) {
FetchType fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() );
if ( FetchType.LAZY.equals( fetchType ) ) {
lazy = true;
}
}
return lazy;
} }
private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class<?> referencedAttributeType) { private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class<?> referencedAttributeType) {
@ -310,12 +303,10 @@ public class AssociationAttribute extends MappedAttribute {
} }
private String determineMapsId() { private String determineMapsId() {
String referencedIdAttributeName;
AnnotationInstance mapsIdAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.MAPS_ID ); AnnotationInstance mapsIdAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.MAPS_ID );
if ( mapsIdAnnotation == null ) { if ( mapsIdAnnotation == null ) {
return null; return null;
} }
if ( !( Nature.MANY_TO_ONE.equals( getNature() ) || Nature.MANY_TO_ONE if ( !( Nature.MANY_TO_ONE.equals( getNature() ) || Nature.MANY_TO_ONE
.equals( getNature() ) ) ) { .equals( getNature() ) ) ) {
throw new MappingException( throw new MappingException(
@ -323,10 +314,7 @@ public class AssociationAttribute extends MappedAttribute {
getContext().getOrigin() getContext().getOrigin()
); );
} }
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
referencedIdAttributeName = JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
return referencedIdAttributeName;
} }
} }

View File

@ -75,7 +75,9 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
* Defines the column values (relational values) for this property. A mapped property can refer to multiple * 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 * column values in case of components or join columns etc
*/ */
private List<Column> columnValues; private List<Column> columnValues = new ArrayList<Column>( );
private List<Column> joinColumnValues = new ArrayList<Column>( );
/** /**
* Is this property an id property (or part thereof). * Is this property an id property (or part thereof).
@ -152,6 +154,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return columnValues; return columnValues;
} }
public List<Column> getJoinColumnValues(){
return joinColumnValues;
}
public boolean isId() { public boolean isId() {
return isId; return isId;
} }
@ -228,14 +234,15 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
} }
private void checkColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) { private void checkColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
columnValues = new ArrayList<Column>(); // single @Column
// single @Column
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation(
annotations, annotations,
JPADotNames.COLUMN JPADotNames.COLUMN
); );
if ( columnAnnotation != null ) { 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 ) ); columnValues.add( new Column( columnAnnotation ) );
} }
@ -245,7 +252,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
JPADotNames.JOIN_COLUMN JPADotNames.JOIN_COLUMN
); );
if ( joinColumnAnnotation != null ) { if ( joinColumnAnnotation != null ) {
columnValues.add( new Column( joinColumnAnnotation ) ); joinColumnValues.add( new Column( joinColumnAnnotation ) );
} }
// @org.hibernate.annotations.Columns // @org.hibernate.annotations.Columns
@ -254,6 +261,9 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
HibernateDotNames.COLUMNS HibernateDotNames.COLUMNS
); );
if ( columnsAnnotation != null ) { 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<AnnotationInstance> columnsList = Arrays.asList( List<AnnotationInstance> columnsList = Arrays.asList(
JandexHelper.getValue( columnsAnnotation, "value", AnnotationInstance[].class ) JandexHelper.getValue( columnsAnnotation, "value", AnnotationInstance[].class )
); );
@ -272,7 +282,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class ) JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class )
); );
for ( AnnotationInstance annotation : columnsList ) { for ( AnnotationInstance annotation : columnsList ) {
columnValues.add( new Column( annotation ) ); joinColumnValues.add( new Column( annotation ) );
} }
} }
} }
@ -311,6 +321,12 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
public DotName getAnnotationDotName() { public DotName getAnnotationDotName() {
return annotationDotName; return annotationDotName;
} }
@Override
public String toString() {
return "Nature{" +annotationDotName.toString()+
'}';
}
} }
} }

View File

@ -69,6 +69,7 @@ public class PluralAssociationAttribute extends AssociationAttribute {
private final boolean isIndexed; private final boolean isIndexed;
// Used for the non-owning side of a ManyToMany relationship // Used for the non-owning side of a ManyToMany relationship
private final String inverseForeignKeyName; private final String inverseForeignKeyName;
private final String explicitForeignKeyName;
private LazyCollectionOption lazyOption; private LazyCollectionOption lazyOption;
@ -103,6 +104,9 @@ public class PluralAssociationAttribute extends AssociationAttribute {
public String getInverseForeignKeyName() { public String getInverseForeignKeyName() {
return inverseForeignKeyName; return inverseForeignKeyName;
} }
public String getExplicitForeignKeyName(){
return explicitForeignKeyName;
}
public Caching getCaching() { public Caching getCaching() {
return caching; return caching;
@ -168,7 +172,21 @@ public class PluralAssociationAttribute extends AssociationAttribute {
this.entityClassInfo = entityClassInfo; this.entityClassInfo = entityClassInfo;
this.whereClause = determineWereClause(); this.whereClause = determineWereClause();
this.orderBy = determineOrderBy(); 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.caching = determineCachingSettings();
this.isExtraLazy = lazyOption == LazyCollectionOption.EXTRA; this.isExtraLazy = lazyOption == LazyCollectionOption.EXTRA;
this.customPersister = determineCustomPersister(); this.customPersister = determineCustomPersister();
@ -250,22 +268,6 @@ public class PluralAssociationAttribute extends AssociationAttribute {
} }
return entityPersisterClass; 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 @Override
protected boolean determineIsLazy(AnnotationInstance associationAnnotation) { protected boolean determineIsLazy(AnnotationInstance associationAnnotation) {
boolean lazy = super.determineIsLazy( associationAnnotation ); boolean lazy = super.determineIsLazy( associationAnnotation );