Skip to content

Commit 8e8844d

Browse files
beikovSanne
authored andcommitted
HHH-14322 Fix HBM many-to-one property ref support
1 parent 0617c99 commit 8e8844d

File tree

2 files changed

+74
-15
lines changed

2 files changed

+74
-15
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/AbstractPluralAttributeSourceImpl.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
*/
77
package org.hibernate.boot.model.source.internal.hbm;
88

9+
import java.io.Serializable;
10+
import java.util.ArrayList;
11+
import java.util.List;
912
import java.util.Optional;
1013

1114
import org.hibernate.AssertionFailure;
1215
import org.hibernate.boot.MappingException;
16+
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmColumnType;
1317
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterType;
1418
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmManyToOneType;
1519
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmRootEntityType;
@@ -72,17 +76,58 @@ protected AbstractPluralAttributeSourceImpl(
7276

7377
Optional<JaxbHbmManyToOneType> jaxbHbmManyToOneTypeOptional = Optional.empty();
7478

75-
if ( pluralAttributeJaxbMapping.isInverse() && pluralAttributeJaxbMapping.getOneToMany() != null ) {
79+
// Our goal here is to find the inverse side of a one to many to figure out against what to join
80+
if ( pluralAttributeJaxbMapping.isInverse() && pluralAttributeJaxbMapping.getOneToMany() != null && pluralAttributeJaxbMapping.getKey().getPropertyRef() == null ) {
7681
String childClass = pluralAttributeJaxbMapping.getOneToMany().getClazz();
7782

7883
if ( childClass != null ) {
84+
// We match by columns as defined in the key
85+
final List<String> keyColumnNames;
86+
if ( pluralAttributeJaxbMapping.getKey().getColumnAttribute() == null ) {
87+
keyColumnNames = new ArrayList<>( pluralAttributeJaxbMapping.getKey().getColumn().size() );
88+
for ( JaxbHbmColumnType jaxbHbmColumnType : pluralAttributeJaxbMapping.getKey().getColumn() ) {
89+
keyColumnNames.add( jaxbHbmColumnType.getName() );
90+
}
91+
}
92+
else {
93+
keyColumnNames = new ArrayList<>( 1 );
94+
keyColumnNames.add( pluralAttributeJaxbMapping.getKey().getColumnAttribute() );
95+
}
7996
jaxbHbmManyToOneTypeOptional = mappingDocument.getDocumentRoot().getClazz()
8097
.stream()
8198
.filter( (JaxbHbmRootEntityType entityType) -> childClass.equals( entityType.getName() ) )
8299
.flatMap( jaxbHbmRootEntityType -> jaxbHbmRootEntityType.getAttributes().stream() )
83-
.filter(
84-
attribute -> attribute instanceof JaxbHbmManyToOneType &&
85-
( (JaxbHbmManyToOneType) attribute ).getPropertyRef() != null )
100+
.filter( attribute -> {
101+
if ( attribute instanceof JaxbHbmManyToOneType ) {
102+
JaxbHbmManyToOneType manyToOneType = (JaxbHbmManyToOneType) attribute;
103+
String manyToOneTypeClass = manyToOneType.getClazz();
104+
String containerClass = container.getAttributeRoleBase().getFullPath();
105+
// Consider many to ones that have no class defined or equal the owner class of the one to many
106+
if ( manyToOneTypeClass == null || manyToOneTypeClass.equals( containerClass ) ) {
107+
if ( manyToOneType.getColumnAttribute() == null ) {
108+
List<Serializable> columns = manyToOneType.getColumnOrFormula();
109+
if ( columns.size() != keyColumnNames.size() ) {
110+
return false;
111+
}
112+
for ( int i = 0; i < columns.size(); i++ ) {
113+
Serializable column = columns.get( i );
114+
String keyColumn = keyColumnNames.get( i );
115+
if ( !( column instanceof JaxbHbmColumnType ) || !( (JaxbHbmColumnType) column )
116+
.getName()
117+
.equals( keyColumn ) ) {
118+
return false;
119+
}
120+
}
121+
}
122+
else {
123+
return keyColumnNames.size() == 1 && keyColumnNames.get( 0 )
124+
.equals( manyToOneType.getColumnAttribute() );
125+
}
126+
return true;
127+
}
128+
}
129+
return false;
130+
})
86131
.map( JaxbHbmManyToOneType.class::cast )
87132
.findFirst();
88133
}
@@ -91,13 +136,12 @@ protected AbstractPluralAttributeSourceImpl(
91136
this.keySource = jaxbHbmManyToOneTypeOptional
92137
.map( jaxbHbmManyToOneType -> new PluralAttributeKeySourceImpl(
93138
sourceMappingDocument(),
139+
pluralAttributeJaxbMapping.getKey(),
94140
jaxbHbmManyToOneType,
95141
container
96142
) ).orElseGet( () -> new PluralAttributeKeySourceImpl(
97143
sourceMappingDocument(),
98-
pluralAttributeJaxbMapping.isInverse() ?
99-
pluralAttributeJaxbMapping.getKey() :
100-
pluralAttributeJaxbMapping.getKey(),
144+
pluralAttributeJaxbMapping.getKey(),
101145
container
102146
) );
103147

hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/PluralAttributeKeySourceImpl.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,31 @@ public List getColumnOrFormulaElements() {
7474

7575
public PluralAttributeKeySourceImpl(
7676
MappingDocument mappingDocument,
77-
final JaxbHbmManyToOneType jaxbKey,
77+
final JaxbHbmKeyType jaxbKey,
78+
final JaxbHbmManyToOneType jaxbManyToOne,
7879
final AttributeSourceContainer container) {
7980
super( mappingDocument );
8081

81-
this.explicitFkName = StringHelper.nullIfEmpty( jaxbKey.getForeignKey() );
82-
this.referencedPropertyName = StringHelper.nullIfEmpty( jaxbKey.getPropertyRef() );
83-
this.cascadeDeletesAtFkLevel = jaxbKey.getOnDelete() != null
84-
&& "cascade".equals( jaxbKey.getOnDelete().value() );
85-
this.nullable = jaxbKey.isNotNull() == null || !jaxbKey.isNotNull();
86-
this.updateable = jaxbKey.isUpdate();
82+
this.explicitFkName = StringHelper.nullIfEmpty( jaxbManyToOne.getForeignKey() );
83+
this.referencedPropertyName = StringHelper.nullIfEmpty( jaxbManyToOne.getPropertyRef() );
84+
if ( jaxbKey.getOnDelete() == null ) {
85+
this.cascadeDeletesAtFkLevel = jaxbManyToOne.getOnDelete() != null && "cascade".equals( jaxbManyToOne.getOnDelete().value() );
86+
}
87+
else {
88+
this.cascadeDeletesAtFkLevel = "cascade".equals( jaxbKey.getOnDelete().value() );
89+
}
90+
if ( jaxbKey.isNotNull() == null ) {
91+
this.nullable = jaxbManyToOne.isNotNull() == null || !jaxbManyToOne.isNotNull();
92+
}
93+
else {
94+
this.nullable = !jaxbKey.isNotNull();
95+
}
96+
if ( jaxbKey.isUpdate() == null ) {
97+
this.updateable = jaxbManyToOne.isUpdate();
98+
}
99+
else {
100+
this.updateable = jaxbKey.isUpdate();
101+
}
87102

88103
this.valueSources = RelationalValueSourceHelper.buildValueSources(
89104
sourceMappingDocument(),
@@ -106,7 +121,7 @@ public String getColumnAttribute() {
106121

107122
@Override
108123
public List getColumnOrFormulaElements() {
109-
return jaxbKey.getColumnOrFormula();
124+
return jaxbKey.getColumn();
110125
}
111126

112127
}

0 commit comments

Comments
 (0)