Skip to content

Commit 6c5f577

Browse files
committed
partial refactoring of AbstractMultiIdEntityLoader and children
Signed-off-by: Gavin King <[email protected]>
1 parent be895c7 commit 6c5f577

File tree

3 files changed

+236
-332
lines changed

3 files changed

+236
-332
lines changed

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

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@
44
*/
55
package org.hibernate.loader.ast.internal;
66

7+
import org.hibernate.LockMode;
8+
import org.hibernate.LockOptions;
9+
import org.hibernate.engine.spi.EntityKey;
710
import org.hibernate.engine.spi.SessionFactoryImplementor;
811
import org.hibernate.event.spi.EventSource;
12+
import org.hibernate.event.spi.LoadEvent;
13+
import org.hibernate.event.spi.LoadEventListener;
14+
import org.hibernate.internal.util.collections.CollectionHelper;
915
import org.hibernate.loader.ast.spi.MultiIdEntityLoader;
1016
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
1117
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
1218
import org.hibernate.metamodel.mapping.EntityMappingType;
19+
import org.hibernate.type.descriptor.java.JavaType;
1320

21+
import java.util.ArrayList;
1422
import java.util.List;
1523

24+
import static org.hibernate.loader.ast.internal.CacheEntityLoaderHelper.loadFromSessionCacheStatic;
25+
1626
/**
1727
* Base support for {@link MultiIdEntityLoader} implementations.
1828
*
@@ -57,7 +67,121 @@ public final <K> List<T> load(K[] ids, MultiIdLoadOptions loadOptions, EventSour
5767
}
5868
}
5969

60-
protected abstract <K> List<T> performOrderedMultiLoad(K[] ids, MultiIdLoadOptions loadOptions, EventSource session);
70+
protected List<T> performOrderedMultiLoad(
71+
Object[] ids,
72+
MultiIdLoadOptions loadOptions,
73+
EventSource session) {
74+
if ( MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) {
75+
MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.tracef( "#performOrderedMultiLoad(`%s`, ..)",
76+
getLoadable().getEntityName() );
77+
}
78+
79+
assert loadOptions.isOrderReturnEnabled();
80+
81+
final boolean coerce = !getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled();
82+
final JavaType<?> idType = getLoadable().getIdentifierMapping().getJavaType();
83+
84+
final LockOptions lockOptions = loadOptions.getLockOptions() == null
85+
? new LockOptions( LockMode.NONE )
86+
: loadOptions.getLockOptions();
87+
88+
final int maxBatchSize = maxBatchSize( ids, loadOptions );
89+
90+
final List<Object> result = CollectionHelper.arrayList( ids.length );
91+
92+
final List<Object> idsInBatch = new ArrayList<>();
93+
final List<Integer> elementPositionsLoadedByBatch = new ArrayList<>();
94+
95+
for ( int i = 0; i < ids.length; i++ ) {
96+
final Object id = coerce ? idType.coerce( ids[i], session ) : ids[i];
97+
final EntityKey entityKey = new EntityKey( id, getLoadable().getEntityPersister() );
98+
99+
if ( !loadFromCaches( loadOptions, session, id, lockOptions, entityKey, result, i ) ) {
100+
// if we did not hit any of the continues above,
101+
// then we need to batch load the entity state.
102+
idsInBatch.add( id );
103+
104+
if ( idsInBatch.size() >= maxBatchSize ) {
105+
// we've hit the allotted max-batch-size, perform an "intermediate load"
106+
loadEntitiesById( idsInBatch, lockOptions, loadOptions, session );
107+
idsInBatch.clear();
108+
}
109+
110+
// Save the EntityKey instance for use later
111+
result.add( i, entityKey );
112+
elementPositionsLoadedByBatch.add( i );
113+
}
114+
}
115+
116+
if ( !idsInBatch.isEmpty() ) {
117+
// we still have ids to load from the processing above since
118+
// the last max-batch-size trigger, perform a load for them
119+
loadEntitiesById( idsInBatch, lockOptions, loadOptions, session );
120+
}
121+
122+
// for each result where we set the EntityKey earlier, replace them
123+
handleResults( loadOptions, session, elementPositionsLoadedByBatch, result );
124+
125+
//noinspection unchecked
126+
return (List<T>) result;
127+
}
128+
129+
protected abstract int maxBatchSize(Object[] ids, MultiIdLoadOptions loadOptions);
130+
131+
protected abstract void handleResults(MultiIdLoadOptions loadOptions, EventSource session, List<Integer> elementPositionsLoadedByBatch, List<Object> result);
132+
133+
protected abstract void loadEntitiesById(List<Object> idsInBatch, LockOptions lockOptions, MultiIdLoadOptions loadOptions, EventSource session);
134+
135+
protected boolean loadFromCaches(
136+
MultiIdLoadOptions loadOptions,
137+
EventSource session,
138+
Object id,
139+
LockOptions lockOptions,
140+
EntityKey entityKey,
141+
List<Object> result,
142+
int i) {
143+
if ( loadOptions.isSessionCheckingEnabled() || loadOptions.isSecondLevelCacheCheckingEnabled() ) {
144+
final LoadEvent loadEvent = new LoadEvent(
145+
id,
146+
getLoadable().getJavaType().getJavaTypeClass().getName(),
147+
lockOptions,
148+
session,
149+
LoaderHelper.getReadOnlyFromLoadQueryInfluencers( session )
150+
);
151+
152+
Object managedEntity = null;
153+
154+
if ( loadOptions.isSessionCheckingEnabled() ) {
155+
// look for it in the Session first
156+
final CacheEntityLoaderHelper.PersistenceContextEntry persistenceContextEntry =
157+
loadFromSessionCacheStatic( loadEvent, entityKey, LoadEventListener.GET );
158+
managedEntity = persistenceContextEntry.getEntity();
159+
160+
if ( managedEntity != null
161+
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
162+
&& !persistenceContextEntry.isManaged() ) {
163+
// put a null in the result
164+
result.add( i, null );
165+
return true;
166+
}
167+
}
168+
169+
if ( managedEntity == null && loadOptions.isSecondLevelCacheCheckingEnabled() ) {
170+
// look for it in the SessionFactory
171+
managedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
172+
loadEvent,
173+
getLoadable().getEntityPersister(),
174+
entityKey
175+
);
176+
}
177+
178+
if ( managedEntity != null ) {
179+
result.add( i, managedEntity );
180+
return true;
181+
}
182+
}
183+
return false;
184+
}
61185

62186
protected abstract <K> List<T> performUnorderedMultiLoad(K[] ids, MultiIdLoadOptions loadOptions, EventSource session);
63187

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

Lines changed: 24 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -73,116 +73,7 @@ public BasicEntityIdentifierMapping getIdentifierMapping() {
7373
}
7474

7575
@Override
76-
protected <K> List<E> performOrderedMultiLoad(K[] ids, MultiIdLoadOptions loadOptions, EventSource session) {
77-
if ( MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) {
78-
MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.tracef(
79-
"MultiIdEntityLoaderArrayParam#performOrderedMultiLoad - %s",
80-
getLoadable().getEntityName()
81-
);
82-
}
83-
84-
assert loadOptions.isOrderReturnEnabled();
85-
86-
final boolean coerce = !getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled();
87-
final JavaType<?> idType = getLoadable().getIdentifierMapping().getJavaType();
88-
89-
final LockOptions lockOptions = loadOptions.getLockOptions() == null
90-
? new LockOptions( LockMode.NONE )
91-
: loadOptions.getLockOptions();
92-
93-
final int maxBatchSize = maxBatchSize( ids, loadOptions );
94-
95-
final List<Object> result = CollectionHelper.arrayList( ids.length );
96-
97-
final List<Object> idsInBatch = new ArrayList<>();
98-
final List<Integer> elementPositionsLoadedByBatch = new ArrayList<>();
99-
100-
for ( int i = 0; i < ids.length; i++ ) {
101-
final Object id = coerce ? idType.coerce( ids[i], session ) : ids[i];
102-
final EntityKey entityKey = new EntityKey( id, getLoadable().getEntityPersister() );
103-
104-
if ( !loadFromCaches( loadOptions, session, id, lockOptions, entityKey, result, i ) ) {
105-
// if we did not hit any of the continues above,
106-
// then we need to batch load the entity state.
107-
idsInBatch.add( id );
108-
109-
if ( idsInBatch.size() >= maxBatchSize ) {
110-
// we've hit the allotted max-batch-size, perform an "intermediate load"
111-
loadEntitiesById( loadOptions, session, lockOptions, idsInBatch );
112-
idsInBatch.clear();
113-
}
114-
115-
// Save the EntityKey instance for use later
116-
result.add( i, entityKey );
117-
elementPositionsLoadedByBatch.add( i );
118-
}
119-
}
120-
121-
if ( !idsInBatch.isEmpty() ) {
122-
// we still have ids to load from the processing above since
123-
// the last max-batch-size trigger, perform a load for them
124-
loadEntitiesById( loadOptions, session, lockOptions, idsInBatch );
125-
}
126-
127-
// for each result where we set the EntityKey earlier, replace them
128-
handleResults( loadOptions, session, elementPositionsLoadedByBatch, result );
129-
130-
//noinspection unchecked
131-
return (List<E>) result;
132-
}
133-
134-
private boolean loadFromCaches(
135-
MultiIdLoadOptions loadOptions,
136-
EventSource session,
137-
Object id,
138-
LockOptions lockOptions,
139-
EntityKey entityKey,
140-
List<Object> result,
141-
int i) {
142-
if ( loadOptions.isSessionCheckingEnabled() || loadOptions.isSecondLevelCacheCheckingEnabled() ) {
143-
final LoadEvent loadEvent = new LoadEvent(
144-
id,
145-
getLoadable().getJavaType().getJavaTypeClass().getName(),
146-
lockOptions,
147-
session,
148-
LoaderHelper.getReadOnlyFromLoadQueryInfluencers( session )
149-
);
150-
151-
Object managedEntity = null;
152-
153-
if ( loadOptions.isSessionCheckingEnabled() ) {
154-
// look for it in the Session first
155-
final PersistenceContextEntry persistenceContextEntry =
156-
loadFromSessionCacheStatic( loadEvent, entityKey, LoadEventListener.GET );
157-
managedEntity = persistenceContextEntry.getEntity();
158-
159-
if ( managedEntity != null
160-
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
161-
&& !persistenceContextEntry.isManaged() ) {
162-
// put a null in the result
163-
result.add( i, null );
164-
return true;
165-
}
166-
}
167-
168-
if ( managedEntity == null && loadOptions.isSecondLevelCacheCheckingEnabled() ) {
169-
// look for it in the SessionFactory
170-
managedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
171-
loadEvent,
172-
getLoadable().getEntityPersister(),
173-
entityKey
174-
);
175-
}
176-
177-
if ( managedEntity != null ) {
178-
result.add( i, managedEntity );
179-
return true;
180-
}
181-
}
182-
return false;
183-
}
184-
185-
private static void handleResults(
76+
protected void handleResults(
18677
MultiIdLoadOptions loadOptions,
18778
EventSource session,
18879
List<Integer> elementPositionsLoadedByBatch,
@@ -209,7 +100,8 @@ private static void handleResults(
209100
}
210101
}
211102

212-
private <K> int maxBatchSize(K[] ids, MultiIdLoadOptions loadOptions) {
103+
@Override
104+
protected int maxBatchSize(Object[] ids, MultiIdLoadOptions loadOptions) {
213105
if ( loadOptions.getBatchSize() != null && loadOptions.getBatchSize() > 0 ) {
214106
return loadOptions.getBatchSize();
215107
}
@@ -225,8 +117,12 @@ private <K> int maxBatchSize(K[] ids, MultiIdLoadOptions loadOptions) {
225117
}
226118
}
227119

228-
private void loadEntitiesById(
229-
MultiIdLoadOptions loadOptions, EventSource session, LockOptions lockOptions, List<Object> idsToLoadFromDatabase) {
120+
@Override
121+
protected void loadEntitiesById(
122+
List<Object> idsToLoadFromDatabase,
123+
LockOptions lockOptions,
124+
MultiIdLoadOptions loadOptions,
125+
EventSource session) {
230126
final SelectStatement sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter(
231127
getLoadable(),
232128
getIdentifierMapping(),
@@ -361,22 +257,16 @@ protected final <R,K> K[] processResolvableEntities(
361257
return ids;
362258
}
363259

364-
final boolean coerce = !getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled();
365-
366260
boolean foundAnyResolvedEntities = false;
367261
List<K> nonResolvedIds = null;
368262

369-
for ( int i = 0; i < ids.length; i++ ) {
370-
final Object id;
371-
if ( coerce ) {
372-
//noinspection unchecked
373-
id = (K) getLoadable().getIdentifierMapping().getJavaType().coerce( ids[i], session );
374-
}
375-
else {
376-
id = ids[i];
377-
}
263+
final boolean coerce = !getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled();
264+
final JavaType<?> idType = getLoadable().getIdentifierMapping().getJavaType();
378265

266+
for ( int i = 0; i < ids.length; i++ ) {
267+
final Object id = coerce ? idType.coerce( ids[i], session ) : ids[i];
379268
final EntityKey entityKey = new EntityKey( id, getLoadable().getEntityPersister() );
269+
380270
final LoadEvent loadEvent = new LoadEvent(
381271
id,
382272
getLoadable().getJavaType().getJavaTypeClass().getName(),
@@ -385,18 +275,15 @@ protected final <R,K> K[] processResolvableEntities(
385275
LoaderHelper.getReadOnlyFromLoadQueryInfluencers( session )
386276
);
387277

388-
Object resolvedEntity = null;
278+
Object managedEntity = null;
389279

390280
// look for it in the Session first
391-
final PersistenceContextEntry persistenceContextEntry = loadFromSessionCacheStatic(
392-
loadEvent,
393-
entityKey,
394-
LoadEventListener.GET
395-
);
281+
final PersistenceContextEntry persistenceContextEntry =
282+
loadFromSessionCacheStatic( loadEvent, entityKey, LoadEventListener.GET );
396283
if ( loadOptions.isSessionCheckingEnabled() ) {
397-
resolvedEntity = persistenceContextEntry.getEntity();
284+
managedEntity = persistenceContextEntry.getEntity();
398285

399-
if ( resolvedEntity != null
286+
if ( managedEntity != null
400287
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
401288
&& !persistenceContextEntry.isManaged() ) {
402289
foundAnyResolvedEntities = true;
@@ -405,25 +292,25 @@ protected final <R,K> K[] processResolvableEntities(
405292
}
406293
}
407294

408-
if ( resolvedEntity == null && loadOptions.isSecondLevelCacheCheckingEnabled() ) {
409-
resolvedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
295+
if ( managedEntity == null && loadOptions.isSecondLevelCacheCheckingEnabled() ) {
296+
managedEntity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache(
410297
loadEvent,
411298
getLoadable().getEntityPersister(),
412299
entityKey
413300
);
414301
}
415302

416-
if ( resolvedEntity != null ) {
303+
if ( managedEntity != null ) {
417304
foundAnyResolvedEntities = true;
418305

419306
//noinspection unchecked
420-
resolutionConsumer.consume( i, entityKey, (R) resolvedEntity);
307+
resolutionConsumer.consume( i, entityKey, (R) managedEntity);
421308
}
422309
else {
423310
if ( nonResolvedIds == null ) {
424311
nonResolvedIds = new ArrayList<>();
425312
}
426-
//noinspection unchecked,CastCanBeRemovedNarrowingVariableType
313+
//noinspection unchecked
427314
nonResolvedIds.add( (K) id );
428315
}
429316
}

0 commit comments

Comments
 (0)