Skip to content

Commit 3a24c70

Browse files
gavinkingsebersole
authored andcommitted
cache the @naturalid loaders
and clean up some of the other loader caching code
1 parent e0ee9f5 commit 3a24c70

File tree

1 file changed

+107
-53
lines changed

1 file changed

+107
-53
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 107 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ public abstract class AbstractEntityPersister
257257
private final EntityLoaderLazyCollection loaders = new EntityLoaderLazyCollection();
258258

259259
private volatile Map<String,EntityLoader> uniqueKeyLoaders;
260+
private volatile Map<LockMode,EntityLoader> naturalIdLoaders;
260261

261262
// SQL strings
262263
private String sqlVersionSelectString;
@@ -2478,40 +2479,56 @@ public Object loadByUniqueKey(
24782479
String propertyName,
24792480
Object uniqueKey,
24802481
SharedSessionContractImplementor session) throws HibernateException {
2481-
return getAppropriateUniqueKeyLoader( propertyName, session ).loadByUniqueKey( session, uniqueKey );
2482+
return getAppropriateUniqueKeyLoader( propertyName, session )
2483+
.loadByUniqueKey( session, uniqueKey );
24822484
}
24832485

24842486
public Object loadByNaturalId(
24852487
Object[] naturalIdValues,
24862488
LockOptions lockOptions,
24872489
SharedSessionContractImplementor session) throws HibernateException {
2488-
//TODO: cache this
2489-
return new EntityLoader(
2490-
this,
2491-
determineValueNullness( naturalIdValues ),
2492-
1,
2493-
lockOptions,
2494-
getFactory(),
2495-
session.getLoadQueryInfluencers()
2496-
).loadByUniqueKey( session, naturalIdValues );
2490+
return getAppropriateNaturalIdLoader( determineValueNullness( naturalIdValues ), lockOptions, session )
2491+
.loadByUniqueKey( session, naturalIdValues );
24972492
}
24982493

2499-
private EntityLoader getAppropriateUniqueKeyLoader(String propertyName, SharedSessionContractImplementor session) {
2500-
final boolean useStaticLoader = !session.getLoadQueryInfluencers().hasEnabledFilters()
2501-
&& !session.getLoadQueryInfluencers().hasEnabledFetchProfiles()
2502-
&& propertyName.indexOf( '.' ) < 0; //ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties
2494+
private EntityLoader getAppropriateNaturalIdLoader(
2495+
boolean[] valueNullness,
2496+
LockOptions lockOptions,
2497+
SharedSessionContractImplementor session) {
2498+
LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers();
2499+
return useStaticNaturalIdLoader( valueNullness, lockOptions, loadQueryInfluencers )
2500+
? naturalIdLoaders.get( lockOptions.getLockMode() ) :
2501+
createNaturalIdLoader( valueNullness, lockOptions, loadQueryInfluencers );
2502+
}
25032503

2504-
if ( useStaticLoader ) {
2505-
final Map<String, EntityLoader> uniqueKeyLoaders = this.uniqueKeyLoaders;
2506-
return uniqueKeyLoaders == null ? null : uniqueKeyLoaders.get( propertyName );
2507-
}
2508-
else {
2509-
return createUniqueKeyLoader(
2510-
propertyMapping.toType( propertyName ),
2511-
propertyMapping.toColumns( propertyName ),
2512-
session.getLoadQueryInfluencers()
2513-
);
2514-
}
2504+
private boolean useStaticNaturalIdLoader(
2505+
boolean[] valueNullness,
2506+
LockOptions lockOptions,
2507+
LoadQueryInfluencers loadQueryInfluencers) {
2508+
return lockOptions.getTimeOut() == LockOptions.WAIT_FOREVER
2509+
&& ArrayHelper.isAllFalse( valueNullness )
2510+
&& !loadQueryInfluencers.hasEnabledFilters()
2511+
&& !loadQueryInfluencers.hasEnabledFetchProfiles();
2512+
}
2513+
2514+
private EntityLoader getAppropriateUniqueKeyLoader(
2515+
String propertyName,
2516+
SharedSessionContractImplementor session) {
2517+
LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers();
2518+
return useStaticUniqueKeyLoader( propertyName, loadQueryInfluencers )
2519+
? uniqueKeyLoaders.get( propertyName )
2520+
: createUniqueKeyLoader(
2521+
propertyMapping.toType( propertyName ),
2522+
propertyMapping.toColumns( propertyName ),
2523+
loadQueryInfluencers
2524+
);
2525+
}
2526+
2527+
private boolean useStaticUniqueKeyLoader(String propertyName, LoadQueryInfluencers loadQueryInfluencers) {
2528+
return !loadQueryInfluencers.hasEnabledFilters()
2529+
&& !loadQueryInfluencers.hasEnabledFetchProfiles()
2530+
//ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties
2531+
&& propertyName.indexOf( '.' ) < 0;
25152532
}
25162533

25172534
public int getPropertyIndex(String propertyName) {
@@ -2521,10 +2538,10 @@ public int getPropertyIndex(String propertyName) {
25212538
protected void createUniqueKeyLoaders() throws MappingException {
25222539
Type[] propertyTypes = getPropertyTypes();
25232540
String[] propertyNames = getPropertyNames();
2524-
for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
2541+
for ( int i = 0; i < propertyUniqueness.length; i++ ) {
25252542
if ( propertyUniqueness[i] ) {
25262543
if ( uniqueKeyLoaders == null ) {
2527-
this.uniqueKeyLoaders = new HashMap<>();
2544+
uniqueKeyLoaders = new HashMap<>();
25282545
}
25292546
//don't need filters for the static loaders
25302547
uniqueKeyLoaders.put(
@@ -2538,6 +2555,9 @@ protected void createUniqueKeyLoaders() throws MappingException {
25382555
//TODO: create uk loaders for component properties
25392556
}
25402557
}
2558+
if ( uniqueKeyLoaders == null ) {
2559+
uniqueKeyLoaders = Collections.emptyMap();
2560+
}
25412561
}
25422562

25432563
private EntityLoader createUniqueKeyLoader(
@@ -2559,6 +2579,40 @@ private EntityLoader createUniqueKeyLoader(
25592579
);
25602580
}
25612581

2582+
protected void createNaturalIdLoaders() throws MappingException {
2583+
if ( hasNaturalIdentifier() ) {
2584+
naturalIdLoaders = new HashMap<>();
2585+
boolean[] valueNullness = new boolean[ getNaturalIdentifierProperties().length ];
2586+
for ( LockMode lockMode : LockMode.values() ) {
2587+
naturalIdLoaders.put(
2588+
lockMode,
2589+
createNaturalIdLoader(
2590+
valueNullness,
2591+
new LockOptions(lockMode),
2592+
LoadQueryInfluencers.NONE
2593+
)
2594+
);
2595+
}
2596+
}
2597+
else {
2598+
naturalIdLoaders = Collections.emptyMap();
2599+
}
2600+
}
2601+
2602+
private EntityLoader createNaturalIdLoader(
2603+
boolean[] valueNullness,
2604+
LockOptions lockOptions,
2605+
LoadQueryInfluencers loadQueryInfluencers) {
2606+
return new EntityLoader(
2607+
this,
2608+
valueNullness,
2609+
1,
2610+
lockOptions,
2611+
getFactory(),
2612+
loadQueryInfluencers
2613+
);
2614+
}
2615+
25622616
protected String getSQLWhereString(String alias) {
25632617
return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias );
25642618
}
@@ -4356,6 +4410,7 @@ public final void postInstantiate() throws MappingException {
43564410

43574411
createLoaders();
43584412
createUniqueKeyLoaders();
4413+
createNaturalIdLoaders();
43594414
createQueryLoader();
43604415

43614416
doPostInstantiate();
@@ -4570,33 +4625,32 @@ protected UniqueEntityLoader getAppropriateLoader(LockOptions lockOptions, Share
45704625
// regardless of any other consideration
45714626
return queryLoader;
45724627
}
4573-
else if ( isAffectedByEnabledFilters( session ) ) {
4574-
// because filters affect the rows returned (because they add
4575-
// restrictions) these need to be next in precedence
4576-
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
4577-
}
4578-
else if ( session.getLoadQueryInfluencers().getInternalFetchProfile() != null && LockMode.UPGRADE.greaterThan(
4579-
lockOptions.getLockMode()
4580-
) ) {
4581-
// Next, we consider whether an 'internal' fetch profile has been set.
4582-
// This indicates a special fetch profile Hibernate needs applied
4583-
// (for its merge loading process e.g.).
4584-
final String internalFetchProfile = session.getLoadQueryInfluencers().getInternalFetchProfile();
4585-
return getLoaderByString( internalFetchProfile );
4586-
}
4587-
else if ( isAffectedByEnabledFetchProfiles( session ) ) {
4588-
// If the session has associated influencers we need to adjust the
4589-
// SQL query used for loading based on those influencers
4590-
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
4591-
}
4592-
else if ( isAffectedByEntityGraph( session ) ) {
4593-
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
4594-
}
4595-
else if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) {
4596-
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
4597-
}
45984628
else {
4599-
return getLoaderByLockMode( lockOptions.getLockMode() );
4629+
LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers();
4630+
if ( isAffectedByEnabledFilters( session ) ) {
4631+
// because filters affect the rows returned (because they add
4632+
// restrictions) these need to be next in precedence
4633+
return createEntityLoader( lockOptions, loadQueryInfluencers );
4634+
}
4635+
else if ( loadQueryInfluencers.getInternalFetchProfile() != null
4636+
&& LockMode.UPGRADE.greaterThan( lockOptions.getLockMode() ) ) {
4637+
// Next, we consider whether an 'internal' fetch profile has been set.
4638+
// This indicates a special fetch profile Hibernate needs applied
4639+
// (for its merge loading process e.g.).
4640+
return getLoaderByString( loadQueryInfluencers.getInternalFetchProfile() );
4641+
}
4642+
else if ( isAffectedByEnabledFetchProfiles( session )
4643+
|| isAffectedByEntityGraph( session ) ) {
4644+
// If the session has associated influencers we need to adjust the
4645+
// SQL query used for loading based on those influencers
4646+
return createEntityLoader( lockOptions, loadQueryInfluencers );
4647+
}
4648+
else if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) {
4649+
return createEntityLoader( lockOptions, loadQueryInfluencers );
4650+
}
4651+
else {
4652+
return getLoaderByLockMode( lockOptions.getLockMode() );
4653+
}
46004654
}
46014655
}
46024656

0 commit comments

Comments
 (0)