HHH-14322 Fix HBM many-to-one property ref support

This commit is contained in:
Christian Beikov 2020-11-11 19:18:59 +01:00 committed by Sanne Grinovero
parent 0617c99e26
commit 8e8844d485
2 changed files with 74 additions and 15 deletions

View File

@ -6,10 +6,14 @@
*/ */
package org.hibernate.boot.model.source.internal.hbm; package org.hibernate.boot.model.source.internal.hbm;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.boot.MappingException; import org.hibernate.boot.MappingException;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmColumnType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmFilterType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmManyToOneType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmManyToOneType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmRootEntityType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmRootEntityType;
@ -72,17 +76,58 @@ public abstract class AbstractPluralAttributeSourceImpl
Optional<JaxbHbmManyToOneType> jaxbHbmManyToOneTypeOptional = Optional.empty(); Optional<JaxbHbmManyToOneType> jaxbHbmManyToOneTypeOptional = Optional.empty();
if ( pluralAttributeJaxbMapping.isInverse() && pluralAttributeJaxbMapping.getOneToMany() != null ) { // Our goal here is to find the inverse side of a one to many to figure out against what to join
if ( pluralAttributeJaxbMapping.isInverse() && pluralAttributeJaxbMapping.getOneToMany() != null && pluralAttributeJaxbMapping.getKey().getPropertyRef() == null ) {
String childClass = pluralAttributeJaxbMapping.getOneToMany().getClazz(); String childClass = pluralAttributeJaxbMapping.getOneToMany().getClazz();
if ( childClass != null ) { if ( childClass != null ) {
// We match by columns as defined in the key
final List<String> keyColumnNames;
if ( pluralAttributeJaxbMapping.getKey().getColumnAttribute() == null ) {
keyColumnNames = new ArrayList<>( pluralAttributeJaxbMapping.getKey().getColumn().size() );
for ( JaxbHbmColumnType jaxbHbmColumnType : pluralAttributeJaxbMapping.getKey().getColumn() ) {
keyColumnNames.add( jaxbHbmColumnType.getName() );
}
}
else {
keyColumnNames = new ArrayList<>( 1 );
keyColumnNames.add( pluralAttributeJaxbMapping.getKey().getColumnAttribute() );
}
jaxbHbmManyToOneTypeOptional = mappingDocument.getDocumentRoot().getClazz() jaxbHbmManyToOneTypeOptional = mappingDocument.getDocumentRoot().getClazz()
.stream() .stream()
.filter( (JaxbHbmRootEntityType entityType) -> childClass.equals( entityType.getName() ) ) .filter( (JaxbHbmRootEntityType entityType) -> childClass.equals( entityType.getName() ) )
.flatMap( jaxbHbmRootEntityType -> jaxbHbmRootEntityType.getAttributes().stream() ) .flatMap( jaxbHbmRootEntityType -> jaxbHbmRootEntityType.getAttributes().stream() )
.filter( .filter( attribute -> {
attribute -> attribute instanceof JaxbHbmManyToOneType && if ( attribute instanceof JaxbHbmManyToOneType ) {
( (JaxbHbmManyToOneType) attribute ).getPropertyRef() != null ) JaxbHbmManyToOneType manyToOneType = (JaxbHbmManyToOneType) attribute;
String manyToOneTypeClass = manyToOneType.getClazz();
String containerClass = container.getAttributeRoleBase().getFullPath();
// Consider many to ones that have no class defined or equal the owner class of the one to many
if ( manyToOneTypeClass == null || manyToOneTypeClass.equals( containerClass ) ) {
if ( manyToOneType.getColumnAttribute() == null ) {
List<Serializable> columns = manyToOneType.getColumnOrFormula();
if ( columns.size() != keyColumnNames.size() ) {
return false;
}
for ( int i = 0; i < columns.size(); i++ ) {
Serializable column = columns.get( i );
String keyColumn = keyColumnNames.get( i );
if ( !( column instanceof JaxbHbmColumnType ) || !( (JaxbHbmColumnType) column )
.getName()
.equals( keyColumn ) ) {
return false;
}
}
}
else {
return keyColumnNames.size() == 1 && keyColumnNames.get( 0 )
.equals( manyToOneType.getColumnAttribute() );
}
return true;
}
}
return false;
})
.map( JaxbHbmManyToOneType.class::cast ) .map( JaxbHbmManyToOneType.class::cast )
.findFirst(); .findFirst();
} }
@ -91,13 +136,12 @@ public abstract class AbstractPluralAttributeSourceImpl
this.keySource = jaxbHbmManyToOneTypeOptional this.keySource = jaxbHbmManyToOneTypeOptional
.map( jaxbHbmManyToOneType -> new PluralAttributeKeySourceImpl( .map( jaxbHbmManyToOneType -> new PluralAttributeKeySourceImpl(
sourceMappingDocument(), sourceMappingDocument(),
pluralAttributeJaxbMapping.getKey(),
jaxbHbmManyToOneType, jaxbHbmManyToOneType,
container container
) ).orElseGet( () -> new PluralAttributeKeySourceImpl( ) ).orElseGet( () -> new PluralAttributeKeySourceImpl(
sourceMappingDocument(), sourceMappingDocument(),
pluralAttributeJaxbMapping.isInverse() ? pluralAttributeJaxbMapping.getKey(),
pluralAttributeJaxbMapping.getKey() :
pluralAttributeJaxbMapping.getKey(),
container container
) ); ) );

View File

@ -74,16 +74,31 @@ public class PluralAttributeKeySourceImpl
public PluralAttributeKeySourceImpl( public PluralAttributeKeySourceImpl(
MappingDocument mappingDocument, MappingDocument mappingDocument,
final JaxbHbmManyToOneType jaxbKey, final JaxbHbmKeyType jaxbKey,
final JaxbHbmManyToOneType jaxbManyToOne,
final AttributeSourceContainer container) { final AttributeSourceContainer container) {
super( mappingDocument ); super( mappingDocument );
this.explicitFkName = StringHelper.nullIfEmpty( jaxbKey.getForeignKey() ); this.explicitFkName = StringHelper.nullIfEmpty( jaxbManyToOne.getForeignKey() );
this.referencedPropertyName = StringHelper.nullIfEmpty( jaxbKey.getPropertyRef() ); this.referencedPropertyName = StringHelper.nullIfEmpty( jaxbManyToOne.getPropertyRef() );
this.cascadeDeletesAtFkLevel = jaxbKey.getOnDelete() != null if ( jaxbKey.getOnDelete() == null ) {
&& "cascade".equals( jaxbKey.getOnDelete().value() ); this.cascadeDeletesAtFkLevel = jaxbManyToOne.getOnDelete() != null && "cascade".equals( jaxbManyToOne.getOnDelete().value() );
this.nullable = jaxbKey.isNotNull() == null || !jaxbKey.isNotNull(); }
this.updateable = jaxbKey.isUpdate(); else {
this.cascadeDeletesAtFkLevel = "cascade".equals( jaxbKey.getOnDelete().value() );
}
if ( jaxbKey.isNotNull() == null ) {
this.nullable = jaxbManyToOne.isNotNull() == null || !jaxbManyToOne.isNotNull();
}
else {
this.nullable = !jaxbKey.isNotNull();
}
if ( jaxbKey.isUpdate() == null ) {
this.updateable = jaxbManyToOne.isUpdate();
}
else {
this.updateable = jaxbKey.isUpdate();
}
this.valueSources = RelationalValueSourceHelper.buildValueSources( this.valueSources = RelationalValueSourceHelper.buildValueSources(
sourceMappingDocument(), sourceMappingDocument(),
@ -106,7 +121,7 @@ public class PluralAttributeKeySourceImpl
@Override @Override
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return jaxbKey.getColumnOrFormula(); return jaxbKey.getColumn();
} }
} }