|
25 | 25 | import org.hibernate.cache.spi.access.AccessType; |
26 | 26 | import org.hibernate.cache.spi.access.EntityDataAccess; |
27 | 27 | import org.hibernate.cache.spi.entry.CacheEntry; |
| 28 | +import org.hibernate.engine.internal.ForeignKeys; |
28 | 29 | import org.hibernate.engine.spi.EntityEntry; |
29 | 30 | import org.hibernate.engine.spi.EntityHolder; |
30 | 31 | import org.hibernate.engine.spi.EntityKey; |
|
77 | 78 | import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; |
78 | 79 | import org.hibernate.sql.results.jdbc.spi.RowProcessingState; |
79 | 80 | import org.hibernate.stat.spi.StatisticsImplementor; |
| 81 | +import org.hibernate.type.ManyToOneType; |
80 | 82 | import org.hibernate.type.Type; |
81 | 83 | import org.hibernate.type.descriptor.java.MutabilityPlan; |
82 | 84 |
|
@@ -609,6 +611,8 @@ private boolean areKeysEqual(Object key1, Object key2) { |
609 | 611 | protected void resolveInstanceSubInitializers(EntityInitializerData data) { |
610 | 612 | final int subclassId = data.concreteDescriptor.getSubclassId(); |
611 | 613 | final EntityEntry entityEntry = data.entityHolder.getEntityEntry(); |
| 614 | + assert entityEntry != null : "This method should only be called if the entity is already initialized"; |
| 615 | + |
612 | 616 | final Initializer<?>[] initializers; |
613 | 617 | final ImmutableBitSet maybeLazySet; |
614 | 618 | if ( data.entityHolder.getEntityInitializer() == this ) { |
@@ -964,11 +968,13 @@ else if ( lazyInitializer.isUninitialized() ) { |
964 | 968 | registerLoadingEntity( data, data.entityInstanceForNotify ); |
965 | 969 | } |
966 | 970 | else { |
967 | | - data.setState( State.INITIALIZED ); |
968 | 971 | data.entityInstanceForNotify = lazyInitializer.getImplementation(); |
969 | 972 | data.concreteDescriptor = session.getEntityPersister( null, data.entityInstanceForNotify ); |
970 | 973 | resolveEntityKey( data, lazyInitializer.getIdentifier() ); |
971 | 974 | 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 ); |
972 | 978 | } |
973 | 979 | if ( identifierAssembler != null ) { |
974 | 980 | final Initializer<?> initializer = identifierAssembler.getInitializer(); |
@@ -1564,11 +1570,22 @@ protected void registerPossibleUniqueKeyEntries( |
1564 | 1570 | // one used here, which it will be |
1565 | 1571 |
|
1566 | 1572 | 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 | + } |
1567 | 1584 | final EntityUniqueKey entityUniqueKey = new EntityUniqueKey( |
1568 | 1585 | data.concreteDescriptor.getRootEntityDescriptor().getEntityName(), |
1569 | 1586 | //polymorphism comment above |
1570 | 1587 | ukName, |
1571 | | - resolvedEntityState[index], |
| 1588 | + key, |
1572 | 1589 | type, |
1573 | 1590 | session.getFactory() |
1574 | 1591 | ); |
|
0 commit comments