HHH-18608 NPE in EntityInitializerImpl.resolveInstanceSubInitializers
This commit is contained in:
parent
b6c776150a
commit
b5ff96da92
|
@ -296,6 +296,7 @@ import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
|
import org.hibernate.type.ManyToOneType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
|
@ -1301,6 +1302,17 @@ public abstract class AbstractEntityPersister
|
||||||
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
|
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( associationType instanceof ManyToOneType ) {
|
||||||
|
final ManyToOneType manyToOneType = ( (ManyToOneType) associationType );
|
||||||
|
if ( manyToOneType.isLogicalOneToOne() && manyToOneType.isReferenceToPrimaryKey() ) {
|
||||||
|
final AttributeMapping attributeMapping = aep.findAttributeMapping( manyToOneType.getPropertyName() );
|
||||||
|
if ( attributeMapping != null ) {
|
||||||
|
final int index = attributeMapping.getStateArrayPosition();
|
||||||
|
final Type type = aep.getPropertyTypes()[index];
|
||||||
|
uniqueKeys.add( new UniqueKeyEntry( manyToOneType.getPropertyName(), index, type ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CollectionHelper.toSmallList( uniqueKeys );
|
return CollectionHelper.toSmallList( uniqueKeys );
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLaziness
|
||||||
import org.hibernate.cache.spi.access.AccessType;
|
import org.hibernate.cache.spi.access.AccessType;
|
||||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
import org.hibernate.cache.spi.entry.CacheEntry;
|
import org.hibernate.cache.spi.entry.CacheEntry;
|
||||||
|
import org.hibernate.engine.internal.ForeignKeys;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.EntityHolder;
|
import org.hibernate.engine.spi.EntityHolder;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
|
@ -77,6 +78,7 @@ import org.hibernate.sql.results.internal.NullValueAssembler;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||||
|
import org.hibernate.type.ManyToOneType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
|
|
||||||
|
@ -609,6 +611,8 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
||||||
protected void resolveInstanceSubInitializers(EntityInitializerData data) {
|
protected void resolveInstanceSubInitializers(EntityInitializerData data) {
|
||||||
final int subclassId = data.concreteDescriptor.getSubclassId();
|
final int subclassId = data.concreteDescriptor.getSubclassId();
|
||||||
final EntityEntry entityEntry = data.entityHolder.getEntityEntry();
|
final EntityEntry entityEntry = data.entityHolder.getEntityEntry();
|
||||||
|
assert entityEntry != null : "This method should only be called if the entity is already initialized";
|
||||||
|
|
||||||
final Initializer<?>[] initializers;
|
final Initializer<?>[] initializers;
|
||||||
final ImmutableBitSet maybeLazySet;
|
final ImmutableBitSet maybeLazySet;
|
||||||
if ( data.entityHolder.getEntityInitializer() == this ) {
|
if ( data.entityHolder.getEntityInitializer() == this ) {
|
||||||
|
@ -964,11 +968,13 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
||||||
registerLoadingEntity( data, data.entityInstanceForNotify );
|
registerLoadingEntity( data, data.entityInstanceForNotify );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.setState( State.INITIALIZED );
|
|
||||||
data.entityInstanceForNotify = lazyInitializer.getImplementation();
|
data.entityInstanceForNotify = lazyInitializer.getImplementation();
|
||||||
data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify );
|
data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify );
|
||||||
resolveEntityKey( data, lazyInitializer.getIdentifier() );
|
resolveEntityKey( data, lazyInitializer.getIdentifier() );
|
||||||
data.entityHolder = persistenceContext.getEntityHolder( data.entityKey );
|
data.entityHolder = persistenceContext.getEntityHolder( data.entityKey );
|
||||||
|
// Even though the lazyInitializer reports it is initialized, check if the entity holder reports initialized,
|
||||||
|
// because in a nested initialization scenario, this nested initializer must initialize the entity
|
||||||
|
data.setState( data.entityHolder.isInitialized() ? State.INITIALIZED : State.RESOLVED );
|
||||||
}
|
}
|
||||||
if ( identifierAssembler != null ) {
|
if ( identifierAssembler != null ) {
|
||||||
final Initializer<?> initializer = identifierAssembler.getInitializer();
|
final Initializer<?> initializer = identifierAssembler.getInitializer();
|
||||||
|
@ -1564,11 +1570,22 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
||||||
// one used here, which it will be
|
// one used here, which it will be
|
||||||
|
|
||||||
if ( resolvedEntityState[index] != null ) {
|
if ( resolvedEntityState[index] != null ) {
|
||||||
|
final Object key;
|
||||||
|
if ( type instanceof ManyToOneType ) {
|
||||||
|
key = ForeignKeys.getEntityIdentifierIfNotUnsaved(
|
||||||
|
( (ManyToOneType) type ).getAssociatedEntityName(),
|
||||||
|
resolvedEntityState[index],
|
||||||
|
session
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
key = resolvedEntityState[index];
|
||||||
|
}
|
||||||
final EntityUniqueKey entityUniqueKey = new EntityUniqueKey(
|
final EntityUniqueKey entityUniqueKey = new EntityUniqueKey(
|
||||||
data.concreteDescriptor.getRootEntityDescriptor().getEntityName(),
|
data.concreteDescriptor.getRootEntityDescriptor().getEntityName(),
|
||||||
//polymorphism comment above
|
//polymorphism comment above
|
||||||
ukName,
|
ukName,
|
||||||
resolvedEntityState[index],
|
key,
|
||||||
type,
|
type,
|
||||||
session.getFactory()
|
session.getFactory()
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue