HHH-7436 Add support for many-to-many associations to new metamodel

This commit is contained in:
brmeyer 2012-12-03 18:32:24 -05:00
parent 8b706fb3d6
commit 51e7504a50
3 changed files with 63 additions and 21 deletions

View File

@ -590,7 +590,7 @@ private void bindCollectionIndex(
typeHelper.bindJdbcDataType( resolvedElementType, indexBinding.getIndexRelationalValue() );
}
void bindCollectionTableForeignKey(
private void bindCollectionTableForeignKey(
final AbstractPluralAttributeBinding attributeBinding,
final PluralAttributeKeySource keySource,
TableSpecification collectionTable) {
@ -1204,7 +1204,7 @@ private void bindIndexedCollectionTablePrimaryKey(IndexedPluralAttributeBinding
}
}
LocalBindingContext bindingContext() {
public LocalBindingContext bindingContext() {
return bindingContexts.peek();
}
@ -2613,6 +2613,11 @@ private String defaultCollectionJavaTypeName(
private List< Column > determineForeignKeyTargetColumns(
final EntityBinding entityBinding,
ForeignKeyContributingSource foreignKeyContributingSource ) {
// TODO: This method, JoinColumnResolutionContext,
// and JoinColumnResolutionDelegate need re-worked. There is currently
// no way to bind to a collection's inverse foreign key.
final JoinColumnResolutionDelegate fkColumnResolutionDelegate =
foreignKeyContributingSource.getForeignKeyTargetColumnResolutionDelegate();
@ -2650,14 +2655,14 @@ public List< Value > resolveRelationalValuesForAttribute( String attributeName )
if ( referencedAttributeBinding == null ) {
throw bindingContext().makeMappingException(
String.format(
"Could not resolve named property-ref [%s] against entity [%s]",
"Could not resolve named referenced property [%s] against entity [%s]",
attributeName,
entityBinding.getEntity().getName() ) );
}
if ( ! referencedAttributeBinding.getAttribute().isSingular() ) {
throw bindingContext().makeMappingException(
String.format(
"Property-ref [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
"Referenced property [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
attributeName,
entityBinding.getEntity().getName() ) );
}

View File

@ -61,12 +61,21 @@ public ManyToManyPluralAttributeElementSourceImpl(
relationalValueSources.add( new ColumnSourceImpl(
associationAttribute, null, column ) );
}
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
relationalValueSources.add( new ColumnSourceImpl(
associationAttribute, null, column ) );
}
for ( Column column : associationAttribute.getJoinColumnValues() ) {
if ( column.getReferencedColumnName() != null ) {
referencedColumnNames.add( column.getReferencedColumnName() );
}
}
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
if ( column.getReferencedColumnName() != null ) {
referencedColumnNames.add( column.getReferencedColumnName() );
}
}
cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
associationAttribute.getCascadeTypes(),
@ -81,7 +90,7 @@ public String getReferencedEntityName() {
@Override
public String getReferencedEntityAttributeName() {
// JPA does not have the concept of property refs. Instead column names via @JoinColumn are used
// HBM only
return null;
}
@ -118,7 +127,8 @@ public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate(
@Override
public boolean isUnique() {
return false; //To change body of implemented methods use File | Settings | File Templates.
// TODO
return false;
}
@Override
@ -156,8 +166,8 @@ public boolean areValuesNullableByDefault() {
return false;
}
// TODO: Taken from and in duplicate of ToOneAttributeSourceImpl. Look into
// abstracting some of this out.
// TODO: This obviously won't work. We need a new way to handle
// inverse foreign key resolution.
public class AnnotationJoinColumnResolutionDelegate
implements ForeignKeyContributingSource.JoinColumnResolutionDelegate {
private final String logicalJoinTableName;
@ -181,12 +191,24 @@ public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
);
values.add( resolvedColumn );
}
// for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
// if ( column.getReferencedColumnName() == null ) {
// return context.resolveRelationalValuesForAttribute( null );
// }
// org.hibernate.metamodel.spi.relational.Column resolvedColumn = context.resolveColumn(
// column.getReferencedColumnName(),
// logicalJoinTableName,
// null,
// null
// );
// values.add( resolvedColumn );
// }
return values;
}
@Override
public String getReferencedAttributeName() {
// in annotations we are not referencing attribute but column names via @JoinColumn(s)
// HBM only
return null;
}

View File

@ -77,9 +77,9 @@ public class AssociationAttribute extends MappedAttribute {
private final boolean isOrphanRemoval;
private final FetchStyle fetchStyle;
private final boolean mapsId;
private final boolean hasPrimaryKeyJoinColumn;
private final String referencedIdAttributeName;
private final List<Column> joinColumnValues;
private final List<Column> inverseJoinColumnValues;
private final AnnotationInstance joinTableAnnotation;
private AttributeTypeResolver resolver;
@ -127,11 +127,11 @@ public static AssociationAttribute createAssociationAttribute(
this.cascadeTypes = determineCascadeTypes( associationAnnotation );
this.hibernateCascadeTypes = determineHibernateCascadeTypes( annotations );
this.joinColumnValues = determineJoinColumnAnnotations( annotations );
this.inverseJoinColumnValues = determineInverseJoinColumnAnnotations( annotations );
this.fetchStyle = determineFetchStyle();
this.referencedIdAttributeName = determineMapsId();
this.mapsId = referencedIdAttributeName != null;
this.hasPrimaryKeyJoinColumn = determineHasPrimaryKeyJoinColumn();
this.joinTableAnnotation = determineExplicitJoinTable( annotations );
}
@ -172,14 +172,14 @@ public boolean mapsId() {
return mapsId;
}
public boolean hasPrimaryKeyJoinColumn() {
return hasPrimaryKeyJoinColumn;
}
public List<Column> getJoinColumnValues() {
return joinColumnValues;
}
public List<Column> getInverseJoinColumnValues() {
return inverseJoinColumnValues;
}
public AnnotationInstance getJoinTableAnnotation() {
return joinTableAnnotation;
}
@ -416,12 +416,6 @@ private String determineMapsId() {
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
}
private boolean determineHasPrimaryKeyJoinColumn() {
AnnotationInstance primaryKeyJoinColumnAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.PRIMARY_KEY_JOIN_COLUMN );
AnnotationInstance primaryKeyJoinColumnsAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.PRIMARY_KEY_JOIN_COLUMNS );
return primaryKeyJoinColumnAnnotation != null || primaryKeyJoinColumnsAnnotation != null;
}
private List<Column> determineJoinColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
ArrayList<Column> joinColumns = new ArrayList<Column>();
@ -480,6 +474,27 @@ private List<Column> determineJoinColumnAnnotations(Map<DotName, List<Annotation
return joinColumns;
}
private List<Column> determineInverseJoinColumnAnnotations(
Map<DotName, List<AnnotationInstance>> annotations) {
ArrayList<Column> inverseJoinColumns = new ArrayList<Column>();
// @JoinColumn as part of @JoinTable
AnnotationInstance joinTableAnnotation = JandexHelper
.getSingleAnnotation( annotations, JPADotNames.JOIN_TABLE );
if(joinTableAnnotation != null) {
List<AnnotationInstance> columnsList = Arrays.asList(
JandexHelper.getValue( joinTableAnnotation,
"inverseJoinColumns", AnnotationInstance[].class )
);
for ( AnnotationInstance annotation : columnsList ) {
inverseJoinColumns.add( new Column( annotation ) );
}
}
inverseJoinColumns.trimToSize();
return inverseJoinColumns;
}
private AnnotationInstance determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance annotationInstance = null;
AnnotationInstance collectionTableAnnotation = JandexHelper.getSingleAnnotation(