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.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 ) {

View File

@ -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<RelationalValueSource> relationalValueSources() {
// TODO
return Collections.emptyList();
if(attribute.getJoinColumnValues().isEmpty())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 {
private final PluralAssociationAttribute attribute;
public JoinColumnResolutionDelegateImpl(PluralAssociationAttribute attribute) {
this.attribute = attribute;
}
@Override
public List<Value> 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;
}
}
}

View File

@ -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 );
}
}

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
* 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).
@ -152,6 +154,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return columnValues;
}
public List<Column> getJoinColumnValues(){
return joinColumnValues;
}
public boolean isId() {
return isId;
}
@ -228,14 +234,15 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
}
private void checkColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
columnValues = new ArrayList<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<MappedAttribute> {
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<MappedAttribute> {
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<AnnotationInstance> columnsList = Arrays.asList(
JandexHelper.getValue( columnsAnnotation, "value", AnnotationInstance[].class )
);
@ -272,7 +282,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
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<MappedAttribute> {
public DotName getAnnotationDotName() {
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;
// 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 );