Skip to content

Commit

Permalink
HHH-18608 NPE in EntityInitializerImpl.resolveInstanceSubInitializers
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 committed Sep 27, 2024
1 parent 157a2ba commit 14498b0
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.ManyToOneType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
Expand Down Expand Up @@ -1183,6 +1184,15 @@ private static List<UniqueKeyEntry> initUniqueKeyEntries(final AbstractEntityPer
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
}
}
else if ( associationType instanceof ManyToOneType manyToOneType
&& 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 toSmallList( uniqueKeys );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityHolder;
import org.hibernate.engine.spi.EntityKey;
Expand Down Expand Up @@ -75,6 +76,7 @@
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.ManyToOneType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.MutabilityPlan;

Expand Down Expand Up @@ -622,6 +624,8 @@ private boolean areKeysEqual(Object key1, Object key2) {
protected void resolveInstanceSubInitializers(EntityInitializerData data) {
final int subclassId = data.concreteDescriptor.getSubclassId();
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 ImmutableBitSet maybeLazySet;
if ( data.entityHolder.getEntityInitializer() == this ) {
Expand Down Expand Up @@ -981,11 +985,13 @@ else if ( lazyInitializer.isUninitialized() ) {
registerLoadingEntity( data, data.entityInstanceForNotify );
}
else {
data.setState( State.INITIALIZED );
data.entityInstanceForNotify = lazyInitializer.getImplementation();
data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify );
resolveEntityKey( data, lazyInitializer.getIdentifier() );
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 ) {
final Initializer<?> initializer = identifierAssembler.getInitializer();
Expand Down Expand Up @@ -1582,11 +1588,22 @@ protected void registerPossibleUniqueKeyEntries(
// one used here, which it will be

if ( resolvedEntityState[index] != null ) {
final Object key;
if ( type instanceof ManyToOneType manyToOneType ) {
key = ForeignKeys.getEntityIdentifierIfNotUnsaved(
manyToOneType.getAssociatedEntityName(),
resolvedEntityState[index],
session
);
}
else {
key = resolvedEntityState[index];
}
final EntityUniqueKey entityUniqueKey = new EntityUniqueKey(
data.concreteDescriptor.getRootEntityDescriptor().getEntityName(),
//polymorphism comment above
ukName,
resolvedEntityState[index],
key,
type,
session.getFactory()
);
Expand Down

0 comments on commit 14498b0

Please sign in to comment.