HHH-17925 Allow mapping join column on single attribute of composite id

This commit is contained in:
Marco Belladelli 2024-04-22 11:48:20 +02:00
parent 3652897800
commit 61632590a0
4 changed files with 24 additions and 16 deletions

View File

@ -27,6 +27,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.TypeHelper;
@ -324,13 +325,16 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
@Override
public Object getLoadedValue(String propertyName) {
return loadedState == null || propertyName == null
? null
: loadedState[ propertyIndex( propertyName ) ];
if ( loadedState == null || propertyName == null ) {
return null;
}
final int index = propertyIndex( propertyName );
return index < 0 ? null : loadedState[index];
}
private int propertyIndex(String propertyName) {
return persister.findAttributeMapping( propertyName ).getStateArrayPosition();
final AttributeMapping attributeMapping = persister.findAttributeMapping( propertyName );
return attributeMapping != null ? attributeMapping.getStateArrayPosition() : -1;
}
@Override

View File

@ -765,7 +765,7 @@ public class MappingModelCreationHelper {
fkTargetPart = collectionDescriptor.getOwnerEntityPersister().getIdentifierMapping();
}
else {
fkTargetPart = declaringType.findContainingEntityMapping().findAttributeMapping( lhsPropertyName );
fkTargetPart = declaringType.findContainingEntityMapping().findSubPart( lhsPropertyName );
}
if ( keyType instanceof BasicType ) {

View File

@ -1263,9 +1263,12 @@ public abstract class AbstractEntityPersister
final AssociationType associationType = (AssociationType) propertyType;
final String ukName = associationType.getLHSPropertyName();
if ( ukName != null ) {
final int index = aep.findAttributeMapping( ukName ).getStateArrayPosition();
final Type type = aep.getPropertyTypes()[index];
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
final AttributeMapping attributeMapping = aep.findAttributeMapping( ukName );
if ( attributeMapping != null ) {
final int index = attributeMapping.getStateArrayPosition();
final Type type = aep.getPropertyTypes()[index];
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
}
}
}
}
@ -4515,10 +4518,10 @@ public abstract class AbstractEntityPersister
}
}
else if ( identifierMapping instanceof NonAggregatedIdentifierMapping ) {
final EmbeddedAttributeMapping embeddedAttributeMapping =
(EmbeddedAttributeMapping) findAttributeMapping( NavigableRole.IDENTIFIER_MAPPER_PROPERTY );
final AttributeMapping mapping = embeddedAttributeMapping == null ? null
: embeddedAttributeMapping.getMappedType().findAttributeMapping( basePropertyName );
final AttributeMapping mapping = ( (NonAggregatedIdentifierMapping) identifierMapping ).findSubPart(
propertyName,
null
).asAttributeMapping();
if ( mapping != null ) {
baseValue = mapping.getAttributeMetadata().getPropertyAccess().getGetter().get( object );
if ( dotIndex != -1 ) {

View File

@ -369,7 +369,7 @@ public abstract class CollectionType extends AbstractType implements Association
public Object getKeyOfOwner(Object owner, SharedSessionContractImplementor session) {
final PersistenceContext pc = session.getPersistenceContextInternal();
EntityEntry entityEntry = pc.getEntry( owner );
final EntityEntry entityEntry = pc.getEntry( owner );
if ( entityEntry == null ) {
// This just handles a particular case of component
// projection, perhaps get rid of it and throw an exception
@ -385,9 +385,10 @@ public abstract class CollectionType extends AbstractType implements Association
// later in the mapping document) - now, we could try and use e.getStatus()
// to decide to semiResolve(), trouble is that initializeEntity() reuses
// the same array for resolved and hydrated values
Object id = entityEntry.getLoadedState() != null
? entityEntry.getLoadedValue( foreignKeyPropertyName )
: entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName );
final Object loadedValue = entityEntry.getLoadedValue( foreignKeyPropertyName );
final Object id = loadedValue == null ?
entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName ) :
loadedValue;
// NOTE VERY HACKISH WORKAROUND!!
// TODO: Fix this so it will work for non-POJO entity mode