Skip to content

Commit b5ff96d

Browse files
committed
HHH-18608 NPE in EntityInitializerImpl.resolveInstanceSubInitializers
1 parent b6c7761 commit b5ff96d

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@
296296
import org.hibernate.type.ComponentType;
297297
import org.hibernate.type.CompositeType;
298298
import org.hibernate.type.EntityType;
299+
import org.hibernate.type.ManyToOneType;
299300
import org.hibernate.type.Type;
300301
import org.hibernate.type.descriptor.java.JavaType;
301302
import org.hibernate.type.descriptor.java.MutabilityPlan;
@@ -1301,6 +1302,17 @@ private static List<UniqueKeyEntry> initUniqueKeyEntries(final AbstractEntityPer
13011302
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
13021303
}
13031304
}
1305+
else if ( associationType instanceof ManyToOneType ) {
1306+
final ManyToOneType manyToOneType = ( (ManyToOneType) associationType );
1307+
if ( manyToOneType.isLogicalOneToOne() && manyToOneType.isReferenceToPrimaryKey() ) {
1308+
final AttributeMapping attributeMapping = aep.findAttributeMapping( manyToOneType.getPropertyName() );
1309+
if ( attributeMapping != null ) {
1310+
final int index = attributeMapping.getStateArrayPosition();
1311+
final Type type = aep.getPropertyTypes()[index];
1312+
uniqueKeys.add( new UniqueKeyEntry( manyToOneType.getPropertyName(), index, type ) );
1313+
}
1314+
}
1315+
}
13041316
}
13051317
}
13061318
return CollectionHelper.toSmallList( uniqueKeys );

hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityInitializerImpl.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.hibernate.cache.spi.access.AccessType;
2626
import org.hibernate.cache.spi.access.EntityDataAccess;
2727
import org.hibernate.cache.spi.entry.CacheEntry;
28+
import org.hibernate.engine.internal.ForeignKeys;
2829
import org.hibernate.engine.spi.EntityEntry;
2930
import org.hibernate.engine.spi.EntityHolder;
3031
import org.hibernate.engine.spi.EntityKey;
@@ -77,6 +78,7 @@
7778
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
7879
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
7980
import org.hibernate.stat.spi.StatisticsImplementor;
81+
import org.hibernate.type.ManyToOneType;
8082
import org.hibernate.type.Type;
8183
import org.hibernate.type.descriptor.java.MutabilityPlan;
8284

@@ -609,6 +611,8 @@ private boolean areKeysEqual(Object key1, Object key2) {
609611
protected void resolveInstanceSubInitializers(EntityInitializerData data) {
610612
final int subclassId = data.concreteDescriptor.getSubclassId();
611613
final EntityEntry entityEntry = data.entityHolder.getEntityEntry();
614+
assert entityEntry != null : "This method should only be called if the entity is already initialized";
615+
612616
final Initializer<?>[] initializers;
613617
final ImmutableBitSet maybeLazySet;
614618
if ( data.entityHolder.getEntityInitializer() == this ) {
@@ -964,11 +968,13 @@ else if ( lazyInitializer.isUninitialized() ) {
964968
registerLoadingEntity( data, data.entityInstanceForNotify );
965969
}
966970
else {
967-
data.setState( State.INITIALIZED );
968971
data.entityInstanceForNotify = lazyInitializer.getImplementation();
969972
data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify );
970973
resolveEntityKey( data, lazyInitializer.getIdentifier() );
971974
data.entityHolder = persistenceContext.getEntityHolder( data.entityKey );
975+
// Even though the lazyInitializer reports it is initialized, check if the entity holder reports initialized,
976+
// because in a nested initialization scenario, this nested initializer must initialize the entity
977+
data.setState( data.entityHolder.isInitialized() ? State.INITIALIZED : State.RESOLVED );
972978
}
973979
if ( identifierAssembler != null ) {
974980
final Initializer<?> initializer = identifierAssembler.getInitializer();
@@ -1564,11 +1570,22 @@ protected void registerPossibleUniqueKeyEntries(
15641570
// one used here, which it will be
15651571

15661572
if ( resolvedEntityState[index] != null ) {
1573+
final Object key;
1574+
if ( type instanceof ManyToOneType ) {
1575+
key = ForeignKeys.getEntityIdentifierIfNotUnsaved(
1576+
( (ManyToOneType) type ).getAssociatedEntityName(),
1577+
resolvedEntityState[index],
1578+
session
1579+
);
1580+
}
1581+
else {
1582+
key = resolvedEntityState[index];
1583+
}
15671584
final EntityUniqueKey entityUniqueKey = new EntityUniqueKey(
15681585
data.concreteDescriptor.getRootEntityDescriptor().getEntityName(),
15691586
//polymorphism comment above
15701587
ukName,
1571-
resolvedEntityState[index],
1588+
key,
15721589
type,
15731590
session.getFactory()
15741591
);

0 commit comments

Comments
 (0)