Skip to content

Commit 51e7504

Browse files
committed
HHH-7436 Add support for many-to-many associations to new metamodel
1 parent 8b706fb commit 51e7504

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ private void bindCollectionIndex(
590590
typeHelper.bindJdbcDataType( resolvedElementType, indexBinding.getIndexRelationalValue() );
591591
}
592592

593-
void bindCollectionTableForeignKey(
593+
private void bindCollectionTableForeignKey(
594594
final AbstractPluralAttributeBinding attributeBinding,
595595
final PluralAttributeKeySource keySource,
596596
TableSpecification collectionTable) {
@@ -1204,7 +1204,7 @@ private void bindIndexedCollectionTablePrimaryKey(IndexedPluralAttributeBinding
12041204
}
12051205
}
12061206

1207-
LocalBindingContext bindingContext() {
1207+
public LocalBindingContext bindingContext() {
12081208
return bindingContexts.peek();
12091209
}
12101210

@@ -2613,6 +2613,11 @@ private String defaultCollectionJavaTypeName(
26132613
private List< Column > determineForeignKeyTargetColumns(
26142614
final EntityBinding entityBinding,
26152615
ForeignKeyContributingSource foreignKeyContributingSource ) {
2616+
2617+
// TODO: This method, JoinColumnResolutionContext,
2618+
// and JoinColumnResolutionDelegate need re-worked. There is currently
2619+
// no way to bind to a collection's inverse foreign key.
2620+
26162621
final JoinColumnResolutionDelegate fkColumnResolutionDelegate =
26172622
foreignKeyContributingSource.getForeignKeyTargetColumnResolutionDelegate();
26182623

@@ -2650,14 +2655,14 @@ public List< Value > resolveRelationalValuesForAttribute( String attributeName )
26502655
if ( referencedAttributeBinding == null ) {
26512656
throw bindingContext().makeMappingException(
26522657
String.format(
2653-
"Could not resolve named property-ref [%s] against entity [%s]",
2658+
"Could not resolve named referenced property [%s] against entity [%s]",
26542659
attributeName,
26552660
entityBinding.getEntity().getName() ) );
26562661
}
26572662
if ( ! referencedAttributeBinding.getAttribute().isSingular() ) {
26582663
throw bindingContext().makeMappingException(
26592664
String.format(
2660-
"Property-ref [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
2665+
"Referenced property [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
26612666
attributeName,
26622667
entityBinding.getEntity().getName() ) );
26632668
}

hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToManyPluralAttributeElementSourceImpl.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,21 @@ public ManyToManyPluralAttributeElementSourceImpl(
6161
relationalValueSources.add( new ColumnSourceImpl(
6262
associationAttribute, null, column ) );
6363
}
64+
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
65+
relationalValueSources.add( new ColumnSourceImpl(
66+
associationAttribute, null, column ) );
67+
}
6468

6569
for ( Column column : associationAttribute.getJoinColumnValues() ) {
6670
if ( column.getReferencedColumnName() != null ) {
6771
referencedColumnNames.add( column.getReferencedColumnName() );
6872
}
6973
}
74+
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
75+
if ( column.getReferencedColumnName() != null ) {
76+
referencedColumnNames.add( column.getReferencedColumnName() );
77+
}
78+
}
7079

7180
cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
7281
associationAttribute.getCascadeTypes(),
@@ -81,7 +90,7 @@ public String getReferencedEntityName() {
8190

8291
@Override
8392
public String getReferencedEntityAttributeName() {
84-
// JPA does not have the concept of property refs. Instead column names via @JoinColumn are used
93+
// HBM only
8594
return null;
8695
}
8796

@@ -118,7 +127,8 @@ public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate(
118127

119128
@Override
120129
public boolean isUnique() {
121-
return false; //To change body of implemented methods use File | Settings | File Templates.
130+
// TODO
131+
return false;
122132
}
123133

124134
@Override
@@ -156,8 +166,8 @@ public boolean areValuesNullableByDefault() {
156166
return false;
157167
}
158168

159-
// TODO: Taken from and in duplicate of ToOneAttributeSourceImpl. Look into
160-
// abstracting some of this out.
169+
// TODO: This obviously won't work. We need a new way to handle
170+
// inverse foreign key resolution.
161171
public class AnnotationJoinColumnResolutionDelegate
162172
implements ForeignKeyContributingSource.JoinColumnResolutionDelegate {
163173
private final String logicalJoinTableName;
@@ -181,12 +191,24 @@ public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
181191
);
182192
values.add( resolvedColumn );
183193
}
194+
// for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
195+
// if ( column.getReferencedColumnName() == null ) {
196+
// return context.resolveRelationalValuesForAttribute( null );
197+
// }
198+
// org.hibernate.metamodel.spi.relational.Column resolvedColumn = context.resolveColumn(
199+
// column.getReferencedColumnName(),
200+
// logicalJoinTableName,
201+
// null,
202+
// null
203+
// );
204+
// values.add( resolvedColumn );
205+
// }
184206
return values;
185207
}
186208

187209
@Override
188210
public String getReferencedAttributeName() {
189-
// in annotations we are not referencing attribute but column names via @JoinColumn(s)
211+
// HBM only
190212
return null;
191213
}
192214

hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ public class AssociationAttribute extends MappedAttribute {
7777
private final boolean isOrphanRemoval;
7878
private final FetchStyle fetchStyle;
7979
private final boolean mapsId;
80-
private final boolean hasPrimaryKeyJoinColumn;
8180
private final String referencedIdAttributeName;
8281
private final List<Column> joinColumnValues;
82+
private final List<Column> inverseJoinColumnValues;
8383
private final AnnotationInstance joinTableAnnotation;
8484
private AttributeTypeResolver resolver;
8585

@@ -127,11 +127,11 @@ public static AssociationAttribute createAssociationAttribute(
127127
this.cascadeTypes = determineCascadeTypes( associationAnnotation );
128128
this.hibernateCascadeTypes = determineHibernateCascadeTypes( annotations );
129129
this.joinColumnValues = determineJoinColumnAnnotations( annotations );
130+
this.inverseJoinColumnValues = determineInverseJoinColumnAnnotations( annotations );
130131

131132
this.fetchStyle = determineFetchStyle();
132133
this.referencedIdAttributeName = determineMapsId();
133134
this.mapsId = referencedIdAttributeName != null;
134-
this.hasPrimaryKeyJoinColumn = determineHasPrimaryKeyJoinColumn();
135135

136136
this.joinTableAnnotation = determineExplicitJoinTable( annotations );
137137
}
@@ -172,14 +172,14 @@ public boolean mapsId() {
172172
return mapsId;
173173
}
174174

175-
public boolean hasPrimaryKeyJoinColumn() {
176-
return hasPrimaryKeyJoinColumn;
177-
}
178-
179175
public List<Column> getJoinColumnValues() {
180176
return joinColumnValues;
181177
}
182178

179+
public List<Column> getInverseJoinColumnValues() {
180+
return inverseJoinColumnValues;
181+
}
182+
183183
public AnnotationInstance getJoinTableAnnotation() {
184184
return joinTableAnnotation;
185185
}
@@ -416,12 +416,6 @@ private String determineMapsId() {
416416
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
417417
}
418418

419-
private boolean determineHasPrimaryKeyJoinColumn() {
420-
AnnotationInstance primaryKeyJoinColumnAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.PRIMARY_KEY_JOIN_COLUMN );
421-
AnnotationInstance primaryKeyJoinColumnsAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.PRIMARY_KEY_JOIN_COLUMNS );
422-
return primaryKeyJoinColumnAnnotation != null || primaryKeyJoinColumnsAnnotation != null;
423-
}
424-
425419
private List<Column> determineJoinColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
426420
ArrayList<Column> joinColumns = new ArrayList<Column>();
427421

@@ -480,6 +474,27 @@ private List<Column> determineJoinColumnAnnotations(Map<DotName, List<Annotation
480474
return joinColumns;
481475
}
482476

477+
private List<Column> determineInverseJoinColumnAnnotations(
478+
Map<DotName, List<AnnotationInstance>> annotations) {
479+
ArrayList<Column> inverseJoinColumns = new ArrayList<Column>();
480+
481+
// @JoinColumn as part of @JoinTable
482+
AnnotationInstance joinTableAnnotation = JandexHelper
483+
.getSingleAnnotation( annotations, JPADotNames.JOIN_TABLE );
484+
if(joinTableAnnotation != null) {
485+
List<AnnotationInstance> columnsList = Arrays.asList(
486+
JandexHelper.getValue( joinTableAnnotation,
487+
"inverseJoinColumns", AnnotationInstance[].class )
488+
);
489+
for ( AnnotationInstance annotation : columnsList ) {
490+
inverseJoinColumns.add( new Column( annotation ) );
491+
}
492+
}
493+
494+
inverseJoinColumns.trimToSize();
495+
return inverseJoinColumns;
496+
}
497+
483498
private AnnotationInstance determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {
484499
AnnotationInstance annotationInstance = null;
485500
AnnotationInstance collectionTableAnnotation = JandexHelper.getSingleAnnotation(

0 commit comments

Comments
 (0)