Skip to content

Commit 9622f19

Browse files
committed
HHH-18689 Maintain proxy targets when converting cache entries
1 parent c7f8813 commit 9622f19

File tree

2 files changed

+65
-37
lines changed

2 files changed

+65
-37
lines changed

hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
package org.hibernate.engine.internal;
66

77
import org.hibernate.LockMode;
8+
import org.hibernate.engine.spi.EntityEntry;
9+
import org.hibernate.engine.spi.EntityHolder;
810
import org.hibernate.engine.spi.EntityKey;
11+
import org.hibernate.engine.spi.PersistenceContext;
912
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1013
import org.hibernate.engine.spi.Status;
1114
import org.hibernate.persister.entity.EntityPersister;
15+
import org.hibernate.proxy.LazyInitializer;
16+
17+
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
1218

1319
/**
1420
* Functionality relating to the Hibernate two-phase loading process, that may be reused by persisters
@@ -37,16 +43,27 @@ public static void addUninitializedCachedEntity(
3743
final LockMode lockMode,
3844
final Object version,
3945
final SharedSessionContractImplementor session) {
40-
session.getPersistenceContextInternal().addEntity(
46+
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
47+
final EntityHolder entityHolder = persistenceContext.addEntityHolder( key, object );
48+
final EntityEntry entityEntry = persistenceContext.addEntry(
4149
object,
4250
Status.LOADING,
4351
null,
44-
key,
52+
null,
53+
key.getIdentifier(),
4554
version,
4655
lockMode,
4756
true,
4857
persister,
4958
false
5059
);
60+
entityHolder.setEntityEntry( entityEntry );
61+
final Object proxy = entityHolder.getProxy();
62+
if ( proxy != null ) {
63+
// there is already a proxy for this impl
64+
final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
65+
assert lazyInitializer != null;
66+
lazyInitializer.setImplementation( object );
67+
}
5168
}
5269
}

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CacheEntityLoaderHelper.java

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.hibernate.internal.CoreMessageLogger;
3232
import org.hibernate.persister.entity.EntityPersister;
3333
import org.hibernate.pretty.MessageHelper;
34+
import org.hibernate.proxy.LazyInitializer;
3435
import org.hibernate.sql.results.LoadingLogger;
3536
import org.hibernate.stat.internal.StatsHelper;
3637
import org.hibernate.stat.spi.StatisticsImplementor;
@@ -377,16 +378,17 @@ private Object convertCacheEntryToEntity(
377378
final EntityPersister subclassPersister =
378379
factory.getRuntimeMetamodels().getMappingMetamodel()
379380
.getEntityDescriptor( entry.getSubclass() );
381+
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
382+
final EntityHolder oldHolder = persistenceContext.getEntityHolder( entityKey );
380383

381384
final Object entity;
382385
if ( instanceToLoad != null ) {
383386
entity = instanceToLoad;
384387
}
385388
else {
386-
final EntityHolder holder = source.getPersistenceContextInternal().getEntityHolder( entityKey );
387-
if ( holder != null && holder.getEntity() != null ) {
389+
if ( oldHolder != null && oldHolder.getEntity() != null ) {
388390
// Use the entity which might already be
389-
entity = holder.getEntity();
391+
entity = oldHolder.getEntity();
390392
}
391393
else {
392394
entity = source.instantiate( subclassPersister, entityId );
@@ -407,13 +409,34 @@ private Object convertCacheEntryToEntity(
407409
}
408410

409411
// make it circular-reference safe
410-
TwoPhaseLoad.addUninitializedCachedEntity(
411-
entityKey,
412-
entity,
413-
subclassPersister,
414-
LockMode.NONE,
415-
entry.getVersion(),
416-
source
412+
final EntityHolder holder = persistenceContext.addEntityHolder( entityKey, entity );
413+
final Object proxy = holder.getProxy();
414+
final boolean isReadOnly;
415+
if ( proxy != null ) {
416+
// there is already a proxy for this impl
417+
// only set the status to read-only if the proxy is read-only
418+
final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
419+
assert lazyInitializer != null;
420+
lazyInitializer.setImplementation( entity );
421+
422+
isReadOnly = lazyInitializer.isReadOnly();
423+
}
424+
else {
425+
isReadOnly = source.isDefaultReadOnly();
426+
}
427+
holder.setEntityEntry(
428+
persistenceContext.addEntry(
429+
entity,
430+
Status.LOADING,
431+
null,
432+
null,
433+
entityKey.getIdentifier(),
434+
entry.getVersion(),
435+
LockMode.NONE,
436+
true,
437+
persister,
438+
false
439+
)
417440
);
418441

419442
final Type[] types = subclassPersister.getPropertyTypes();
@@ -438,32 +461,20 @@ private Object convertCacheEntryToEntity(
438461
final Object version = getVersion( values, subclassPersister );
439462
LOG.tracef( "Cached Version : %s", version );
440463

441-
final PersistenceContext persistenceContext = source.getPersistenceContext();
442-
443-
final Object proxy = persistenceContext.getProxy( entityKey );
444-
final boolean isReadOnly;
445-
if ( proxy != null ) {
446-
// there is already a proxy for this impl
447-
// only set the status to read-only if the proxy is read-only
448-
isReadOnly = extractLazyInitializer( proxy ).isReadOnly();
449-
}
450-
else {
451-
isReadOnly = source.isDefaultReadOnly();
452-
}
453-
454-
final EntityEntry entityEntry = persistenceContext.addEntry(
455-
entity,
456-
isReadOnly ? Status.READ_ONLY : Status.MANAGED,
457-
values,
458-
null,
459-
entityId,
460-
version,
461-
LockMode.NONE,
462-
true,
463-
subclassPersister,
464-
false
464+
holder.setEntityEntry(
465+
persistenceContext.addEntry(
466+
entity,
467+
isReadOnly ? Status.READ_ONLY : Status.MANAGED,
468+
values,
469+
null,
470+
entityId,
471+
version,
472+
LockMode.NONE,
473+
true,
474+
subclassPersister,
475+
false
476+
)
465477
);
466-
persistenceContext.getEntityHolder( entityKey ).setEntityEntry( entityEntry );
467478
subclassPersister.afterInitialize( entity, source );
468479
persistenceContext.initializeNonLazyCollections();
469480

0 commit comments

Comments
 (0)