Skip to content

Commit ac74e3b

Browse files
committed
HHH-18777 EntityHolder map optimization to avoid double accesses
1 parent 9622f19 commit ac74e3b

File tree

1 file changed

+52
-38
lines changed

1 file changed

+52
-38
lines changed

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

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ the following fields are used in all circumstances, and are not worth (or not su
116116
// Loaded entity instances, by EntityKey
117117
private HashMap<EntityKey, EntityHolderImpl> entitiesByKey;
118118

119+
// New entity holder cached instance
120+
private EntityHolderImpl newEntityHolder;
121+
119122
// Loaded entity instances, by EntityUniqueKey
120123
private HashMap<EntityUniqueKey, Object> entitiesByUniqueKey;
121124

@@ -182,6 +185,13 @@ private Map<EntityKey, EntityHolderImpl> getOrInitializeEntitiesByKey() {
182185
return entitiesByKey;
183186
}
184187

188+
private EntityHolderImpl getOrInitializeNewHolder() {
189+
if ( newEntityHolder == null ) {
190+
return newEntityHolder = new EntityHolderImpl();
191+
}
192+
return newEntityHolder;
193+
}
194+
185195
@Override
186196
public boolean isStateless() {
187197
return false;
@@ -390,8 +400,8 @@ public EntityHolder claimEntityHolderIfPossible(
390400
JdbcValuesSourceProcessingState processingState,
391401
EntityInitializer<?> initializer) {
392402
final Map<EntityKey, EntityHolderImpl> entityHolderMap = getOrInitializeEntitiesByKey();
393-
final EntityHolderImpl oldHolder = entityHolderMap.get( key );
394-
final EntityHolderImpl holder;
403+
EntityHolderImpl holder = getOrInitializeNewHolder().withEntity( key, key.getPersister(), entity );
404+
final EntityHolderImpl oldHolder = entityHolderMap.putIfAbsent( key, newEntityHolder );
395405
if ( oldHolder != null ) {
396406
if ( entity != null ) {
397407
assert oldHolder.entity == null || oldHolder.entity == entity;
@@ -411,7 +421,7 @@ public EntityHolder claimEntityHolderIfPossible(
411421
holder = oldHolder;
412422
}
413423
else {
414-
entityHolderMap.put( key, holder = EntityHolderImpl.forEntity( key, key.getPersister(), entity ) );
424+
newEntityHolder = null;
415425
}
416426
assert holder.entityInitializer == null || holder.entityInitializer == initializer;
417427
holder.entityInitializer = initializer;
@@ -494,16 +504,14 @@ public void addEntity(EntityKey key, Object entity) {
494504
@Override
495505
public EntityHolder addEntityHolder(EntityKey key, Object entity) {
496506
final Map<EntityKey, EntityHolderImpl> entityHolderMap = getOrInitializeEntitiesByKey();
497-
final EntityHolderImpl oldHolder = entityHolderMap.get( key );
498-
final EntityHolderImpl holder;
507+
EntityHolderImpl holder = getOrInitializeNewHolder().withEntity( key, key.getPersister(), entity );
508+
final EntityHolderImpl oldHolder = entityHolderMap.putIfAbsent( key, holder );
499509
if ( oldHolder != null ) {
500-
// assert oldHolder.entity == null || oldHolder.entity == entity;
501510
oldHolder.entity = entity;
502511
holder = oldHolder;
503512
}
504513
else {
505-
holder = EntityHolderImpl.forEntity( key, key.getPersister(), entity );
506-
entityHolderMap.put( key, holder );
514+
newEntityHolder = null;
507515
}
508516
holder.state = EntityHolderState.INITIALIZED;
509517
final BatchFetchQueue fetchQueue = this.batchFetchQueue;
@@ -783,14 +791,15 @@ private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
783791
final EntityKey key = session.generateEntityKey( li.getInternalIdentifier(), persister );
784792
// any earlier proxy takes precedence
785793
final Map<EntityKey, EntityHolderImpl> entityHolderMap = getOrInitializeEntitiesByKey();
786-
final EntityHolderImpl oldHolder = entityHolderMap.get( key );
794+
final EntityHolderImpl holder = getOrInitializeNewHolder().withProxy( key, persister, proxy );
795+
final EntityHolderImpl oldHolder = entityHolderMap.putIfAbsent( key, holder );
787796
if ( oldHolder != null ) {
788797
if ( oldHolder.proxy == null ) {
789798
oldHolder.proxy = proxy;
790799
}
791800
}
792801
else {
793-
entityHolderMap.put( key, EntityHolderImpl.forProxy( key, persister, proxy ) );
802+
newEntityHolder = null;
794803
}
795804
proxy.getHibernateLazyInitializer().setSession( session );
796805
}
@@ -929,16 +938,16 @@ public Object proxyFor(EntityHolder holder, EntityPersister persister) {
929938
@Override
930939
public void addEnhancedProxy(EntityKey key, PersistentAttributeInterceptable entity) {
931940
final Map<EntityKey, EntityHolderImpl> entityHolderMap = getOrInitializeEntitiesByKey();
932-
final EntityHolderImpl oldHolder = entityHolderMap.get( key );
933-
final EntityHolderImpl holder;
941+
final EntityHolderImpl holder = getOrInitializeNewHolder().withEntity( key, key.getPersister(), entity );
942+
final EntityHolderImpl oldHolder = entityHolderMap.putIfAbsent( key, holder );
934943
if ( oldHolder != null ) {
935944
oldHolder.entity = entity;
936-
holder = oldHolder;
945+
oldHolder.state = EntityHolderState.ENHANCED_PROXY;
937946
}
938947
else {
939-
entityHolderMap.put( key, holder = EntityHolderImpl.forEntity( key, key.getPersister(), entity ) );
948+
newEntityHolder = null;
949+
holder.state = EntityHolderState.ENHANCED_PROXY;
940950
}
941-
holder.state = EntityHolderState.ENHANCED_PROXY;
942951
}
943952

944953
@Override
@@ -1229,12 +1238,13 @@ public Object getProxy(EntityKey key) {
12291238
@Override
12301239
public void addProxy(EntityKey key, Object proxy) {
12311240
final Map<EntityKey, EntityHolderImpl> entityHolderMap = getOrInitializeEntitiesByKey();
1232-
final EntityHolderImpl holder = entityHolderMap.get( key );
1233-
if ( holder != null ) {
1234-
holder.proxy = proxy;
1241+
final EntityHolderImpl holder = getOrInitializeNewHolder().withProxy( key, key.getPersister(), proxy );
1242+
final EntityHolderImpl oldHolder = entityHolderMap.putIfAbsent( key, holder );
1243+
if ( oldHolder != null ) {
1244+
oldHolder.proxy = proxy;
12351245
}
12361246
else {
1237-
entityHolderMap.put( key, EntityHolderImpl.forProxy( key, key.getPersister(), proxy ) );
1247+
newEntityHolder = null;
12381248
}
12391249
}
12401250

@@ -1960,7 +1970,7 @@ public static StatefulPersistenceContext deserialize(
19601970
final Object entity = ois.readObject();
19611971
final Object proxy = ois.readObject();
19621972
final EntityHolderState state = (EntityHolderState) ois.readObject();
1963-
final EntityHolderImpl holder = EntityHolderImpl.forEntity( ek, persister, entity );
1973+
final EntityHolderImpl holder = new EntityHolderImpl().withEntity( ek, persister, entity );
19641974
holder.state = state;
19651975
if ( proxy != null ) {
19661976
final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
@@ -2177,20 +2187,15 @@ private void cleanUpInsertedKeysAfterTransaction() {
21772187
}
21782188

21792189
private static class EntityHolderImpl implements EntityHolder, Serializable {
2180-
private final EntityKey entityKey;
2181-
private final EntityPersister descriptor;
2182-
Object entity;
2183-
Object proxy;
2184-
@Nullable EntityEntry entityEntry;
2185-
EntityInitializer<?> entityInitializer;
2186-
EntityHolderState state;
2187-
2188-
private EntityHolderImpl(EntityKey entityKey, EntityPersister descriptor, Object entity, Object proxy) {
2189-
assert entityKey != null && descriptor != null;
2190-
this.entityKey = entityKey;
2191-
this.descriptor = descriptor;
2192-
this.entity = entity;
2193-
this.proxy = proxy;
2190+
private EntityKey entityKey;
2191+
private EntityPersister descriptor;
2192+
private Object entity;
2193+
private Object proxy;
2194+
private @Nullable EntityEntry entityEntry;
2195+
private EntityInitializer<?> entityInitializer;
2196+
private EntityHolderState state;
2197+
2198+
private EntityHolderImpl() {
21942199
this.state = EntityHolderState.UNINITIALIZED;
21952200
}
21962201

@@ -2249,12 +2254,21 @@ public boolean isDetached() {
22492254
return state == EntityHolderState.DETACHED;
22502255
}
22512256

2252-
public static EntityHolderImpl forProxy(EntityKey entityKey, EntityPersister descriptor, Object proxy) {
2253-
return new EntityHolderImpl( entityKey, descriptor, null, proxy );
2257+
public EntityHolderImpl withEntity(EntityKey entityKey, EntityPersister descriptor, Object entity) {
2258+
return withData( entityKey, descriptor, entity, null );
2259+
}
2260+
2261+
public EntityHolderImpl withProxy(EntityKey entityKey, EntityPersister descriptor, Object proxy) {
2262+
return withData( entityKey, descriptor, null, proxy );
22542263
}
22552264

2256-
public static EntityHolderImpl forEntity(EntityKey entityKey, EntityPersister descriptor, Object entity) {
2257-
return new EntityHolderImpl( entityKey, descriptor, entity, null );
2265+
public EntityHolderImpl withData(EntityKey entityKey, EntityPersister descriptor, Object entity, Object proxy) {
2266+
assert entityKey != null && descriptor != null && entityInitializer == null && state == EntityHolderState.UNINITIALIZED;
2267+
this.entityKey = entityKey;
2268+
this.descriptor = descriptor;
2269+
this.entity = entity;
2270+
this.proxy = proxy;
2271+
return this;
22582272
}
22592273
}
22602274

0 commit comments

Comments
 (0)