|
23 | 23 | import org.hibernate.cache.spi.access.AccessType; |
24 | 24 | import org.hibernate.cache.spi.access.EntityDataAccess; |
25 | 25 | import org.hibernate.cache.spi.entry.CacheEntry; |
| 26 | +import org.hibernate.engine.internal.ForeignKeys; |
26 | 27 | import org.hibernate.engine.spi.EntityEntry; |
27 | 28 | import org.hibernate.engine.spi.EntityHolder; |
28 | 29 | import org.hibernate.engine.spi.EntityKey; |
|
75 | 76 | import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; |
76 | 77 | import org.hibernate.sql.results.jdbc.spi.RowProcessingState; |
77 | 78 | import org.hibernate.stat.spi.StatisticsImplementor; |
| 79 | +import org.hibernate.type.ManyToOneType; |
78 | 80 | import org.hibernate.type.Type; |
79 | 81 | import org.hibernate.type.descriptor.java.MutabilityPlan; |
80 | 82 |
|
@@ -622,6 +624,8 @@ private boolean areKeysEqual(Object key1, Object key2) { |
622 | 624 | protected void resolveInstanceSubInitializers(EntityInitializerData data) { |
623 | 625 | final int subclassId = data.concreteDescriptor.getSubclassId(); |
624 | 626 | final EntityEntry entityEntry = data.entityHolder.getEntityEntry(); |
| 627 | + assert entityEntry != null : "This method should only be called if the entity is already initialized"; |
| 628 | + |
625 | 629 | final Initializer<?>[] initializers; |
626 | 630 | final ImmutableBitSet maybeLazySet; |
627 | 631 | if ( data.entityHolder.getEntityInitializer() == this ) { |
@@ -981,11 +985,13 @@ else if ( lazyInitializer.isUninitialized() ) { |
981 | 985 | registerLoadingEntity( data, data.entityInstanceForNotify ); |
982 | 986 | } |
983 | 987 | else { |
984 | | - data.setState( State.INITIALIZED ); |
985 | 988 | data.entityInstanceForNotify = lazyInitializer.getImplementation(); |
986 | 989 | data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify ); |
987 | 990 | resolveEntityKey( data, lazyInitializer.getIdentifier() ); |
988 | 991 | data.entityHolder = persistenceContext.getEntityHolder( data.entityKey ); |
| 992 | + // Even though the lazyInitializer reports it is initialized, check if the entity holder reports initialized, |
| 993 | + // because in a nested initialization scenario, this nested initializer must initialize the entity |
| 994 | + data.setState( data.entityHolder.isInitialized() ? State.INITIALIZED : State.RESOLVED ); |
989 | 995 | } |
990 | 996 | if ( identifierAssembler != null ) { |
991 | 997 | final Initializer<?> initializer = identifierAssembler.getInitializer(); |
@@ -1582,11 +1588,22 @@ protected void registerPossibleUniqueKeyEntries( |
1582 | 1588 | // one used here, which it will be |
1583 | 1589 |
|
1584 | 1590 | if ( resolvedEntityState[index] != null ) { |
| 1591 | + final Object key; |
| 1592 | + if ( type instanceof ManyToOneType manyToOneType ) { |
| 1593 | + key = ForeignKeys.getEntityIdentifierIfNotUnsaved( |
| 1594 | + manyToOneType.getAssociatedEntityName(), |
| 1595 | + resolvedEntityState[index], |
| 1596 | + session |
| 1597 | + ); |
| 1598 | + } |
| 1599 | + else { |
| 1600 | + key = resolvedEntityState[index]; |
| 1601 | + } |
1585 | 1602 | final EntityUniqueKey entityUniqueKey = new EntityUniqueKey( |
1586 | 1603 | data.concreteDescriptor.getRootEntityDescriptor().getEntityName(), |
1587 | 1604 | //polymorphism comment above |
1588 | 1605 | ukName, |
1589 | | - resolvedEntityState[index], |
| 1606 | + key, |
1590 | 1607 | type, |
1591 | 1608 | session.getFactory() |
1592 | 1609 | ); |
|
0 commit comments