HHH-15201 - Composite ID with dynamic-map entities fails with an exception

This commit is contained in:
Steve Ebersole 2022-04-29 13:39:49 -05:00
parent aa6bb1481c
commit 5c12f7a951
4 changed files with 24 additions and 35 deletions

View File

@ -8,7 +8,6 @@ package org.hibernate.metamodel.mapping;
import org.hibernate.engine.spi.IdentifierValue; import org.hibernate.engine.spi.IdentifierValue;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/** /**
@ -43,15 +42,7 @@ public interface EntityIdentifierMapping extends ValueMapping, ModelPart {
Object getIdentifier(Object entity); Object getIdentifier(Object entity);
/**
* @deprecated use {@link #setIdentifier(Object, Object, EntityPersister, SharedSessionContractImplementor)} instead.
*/
@Deprecated
void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session); void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session);
default void setIdentifier(Object entity, Object id, EntityPersister entityDescriptor, SharedSessionContractImplementor session){
setIdentifier( entity, id, session );
}
Object instantiate(); Object instantiate();
} }

View File

@ -11,20 +11,20 @@ import java.util.function.BiConsumer;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ManagedMappingType; import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
import org.hibernate.metamodel.mapping.SelectableMappings; import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -44,6 +44,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
*/ */
public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapping implements NonAggregatedIdentifierMapping { public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapping implements NonAggregatedIdentifierMapping {
private final IdClassEmbeddable idClassEmbeddable; private final IdClassEmbeddable idClassEmbeddable;
private final EntityMappingType entityDescriptor;
private final NonAggregatedIdentifierMapping.IdentifierValueMapper identifierValueMapper; private final NonAggregatedIdentifierMapping.IdentifierValueMapper identifierValueMapper;
@ -63,6 +64,9 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
embeddableTypeDescriptor, embeddableTypeDescriptor,
creationProcess creationProcess
); );
this.entityDescriptor = inverseModelPart.findContainingEntityMapping();
if ( inverseModelPart.getIdClassEmbeddable() == null ) { if ( inverseModelPart.getIdClassEmbeddable() == null ) {
this.idClassEmbeddable = null; this.idClassEmbeddable = null;
this.identifierValueMapper = (NonAggregatedIdentifierMapping.IdentifierValueMapper) super.getEmbeddableTypeDescriptor(); this.identifierValueMapper = (NonAggregatedIdentifierMapping.IdentifierValueMapper) super.getEmbeddableTypeDescriptor();
@ -236,14 +240,6 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
@Override @Override
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) { public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
final EntityPersister entityDescriptor = session.getFactory().getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entity.getClass() );
setIdentifier( entity, id, entityDescriptor, session );
}
@Override
public void setIdentifier(Object entity, Object id, EntityPersister entityDescriptor, SharedSessionContractImplementor session) {
final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings(); final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings();
final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()]; final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()];
@ -263,11 +259,11 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
// otherwise look for an initialized version // otherwise look for an initialized version
propertyValues[position] = persistenceContext.getEntity( entityKey ); propertyValues[position] = persistenceContext.getEntity( entityKey );
if ( propertyValues[position] == null ) { if ( propertyValues[position] == null ) {
// get the association out of the entity itself propertyValues[position] = entityDescriptor
propertyValues[position] = entityDescriptor.getPropertyValue( .findAttributeMapping( toOneAttributeMapping.getAttributeName() )
entity, .getPropertyAccess()
toOneAttributeMapping.getAttributeName() .getGetter()
); .get( entity );
} }
} }
} }

View File

@ -11,7 +11,6 @@ import java.util.function.BiConsumer;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
@ -25,8 +24,8 @@ import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
import org.hibernate.metamodel.mapping.SelectableMappings; import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -47,6 +46,8 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
* Can also be a single {@link jakarta.persistence.Id} with {@link jakarta.persistence.MapsId} * Can also be a single {@link jakarta.persistence.Id} with {@link jakarta.persistence.MapsId}
*/ */
public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentifierMapping implements NonAggregatedIdentifierMapping { public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentifierMapping implements NonAggregatedIdentifierMapping {
private final EntityPersister entityDescriptor;
private final VirtualIdEmbeddable virtualIdEmbeddable; private final VirtualIdEmbeddable virtualIdEmbeddable;
private final IdClassEmbeddable idClassEmbeddable; private final IdClassEmbeddable idClassEmbeddable;
@ -59,6 +60,8 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
String[] rootTableKeyColumnNames, String[] rootTableKeyColumnNames,
MappingModelCreationProcess creationProcess) { MappingModelCreationProcess creationProcess) {
super( entityPersister, rootTableName, creationProcess ); super( entityPersister, rootTableName, creationProcess );
entityDescriptor = entityPersister;
if ( bootEntityDescriptor.getIdentifierMapper() == null if ( bootEntityDescriptor.getIdentifierMapper() == null
|| bootEntityDescriptor.getIdentifierMapper() == bootEntityDescriptor.getIdentifier() ) { || bootEntityDescriptor.getIdentifierMapper() == bootEntityDescriptor.getIdentifier() ) {
// cid -> getIdentifier // cid -> getIdentifier
@ -104,6 +107,13 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
} }
} }
/**
* The entity whose identifier this mapping is the inverse of
*/
public EntityPersister getIdentifiedEntityDescriptor() {
return entityDescriptor;
}
@Override @Override
public EmbeddableMappingType getMappedType() { public EmbeddableMappingType getMappedType() {
return virtualIdEmbeddable; return virtualIdEmbeddable;
@ -256,14 +266,6 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
@Override @Override
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) { public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
final EntityPersister entityDescriptor = session.getFactory().getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entity.getClass() );
setIdentifier( entity, id, entityDescriptor, session );
}
@Override
public void setIdentifier(Object entity, Object id, EntityPersister entityDescriptor, SharedSessionContractImplementor session) {
final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings(); final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings();
final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()]; final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()];

View File

@ -5191,7 +5191,7 @@ public abstract class AbstractEntityPersister
@Override @Override
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) { public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
identifierMapping.setIdentifier( entity, id, this, session ); identifierMapping.setIdentifier( entity, id, session );
} }
@Override @Override