Skip to content

Commit bd761ff

Browse files
usarskyybahusoid
authored andcommitted
Eliminated double Persister resolution in Loader.InstanceNotYetLoaded flow (#476)
Co-authored-by: Roman Artiukhin <[email protected]>
1 parent eb8c13f commit bd761ff

File tree

11 files changed

+69
-54
lines changed

11 files changed

+69
-54
lines changed

src/NHibernate/Async/Loader/Loader.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -740,9 +740,7 @@ private async Task InstanceAlreadyLoadedAsync(DbDataReader rs, int i, ILoadable
740740
return;
741741
}
742742

743-
var instanceClass = await (GetInstanceClassAsync(rs, i, persister, key.Identifier, session, cancellationToken)).ConfigureAwait(false);
744-
entry = entry ?? session.PersistenceContext.GetEntry(obj);
745-
await (UpdateLazyPropertiesFromResultSetAsync(rs, i, obj, instanceClass, key, entry, persister, session, cacheBatchingHandler, cancellationToken)).ConfigureAwait(false);
743+
await (UpdateLazyPropertiesFromResultSetAsync(rs, i, obj, key, entry, persister, session, cacheBatchingHandler, cancellationToken)).ConfigureAwait(false);
746744
}
747745

748746
/// <summary>
@@ -755,7 +753,7 @@ private async Task<object> InstanceNotYetLoadedAsync(DbDataReader dr, int i, ILo
755753
cancellationToken.ThrowIfCancellationRequested();
756754
object obj;
757755

758-
string instanceClass = await (GetInstanceClassAsync(dr, i, persister, key.Identifier, session, cancellationToken)).ConfigureAwait(false);
756+
ILoadable concretePersister = await (GetConcretePersisterAsync(dr, i, persister, key.Identifier, session, cancellationToken)).ConfigureAwait(false);
759757

760758
if (optionalObjectKey != null && key.Equals(optionalObjectKey))
761759
{
@@ -764,7 +762,7 @@ private async Task<object> InstanceNotYetLoadedAsync(DbDataReader dr, int i, ILo
764762
}
765763
else
766764
{
767-
obj = session.Instantiate(instanceClass, key.Identifier);
765+
obj = session.Instantiate(concretePersister, key.Identifier);
768766
}
769767

770768
// need to hydrate it
@@ -773,16 +771,16 @@ private async Task<object> InstanceNotYetLoadedAsync(DbDataReader dr, int i, ILo
773771
// (but don't yet initialize the object itself)
774772
// note that we acquired LockMode.READ even if it was not requested
775773
LockMode acquiredLockMode = lockMode == LockMode.None ? LockMode.Read : lockMode;
776-
await (LoadFromResultSetAsync(dr, i, obj, instanceClass, key, acquiredLockMode, persister, session, cancellationToken)).ConfigureAwait(false);
774+
await (LoadFromResultSetAsync(dr, i, obj, concretePersister, key, acquiredLockMode, persister, session, cancellationToken)).ConfigureAwait(false);
777775

778776
// materialize associations (and initialize the object) later
779777
hydratedObjects.Add(obj);
780778

781779
return obj;
782780
}
783781

784-
private async Task UpdateLazyPropertiesFromResultSetAsync(DbDataReader rs, int i, object obj, string instanceClass, EntityKey key,
785-
EntityEntry entry, ILoadable rootPersister, ISessionImplementor session,
782+
private async Task UpdateLazyPropertiesFromResultSetAsync(DbDataReader rs, int i, object obj, EntityKey key,
783+
EntityEntry optionalEntry, ILoadable rootPersister, ISessionImplementor session,
786784
Action<IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken)
787785
{
788786
cancellationToken.ThrowIfCancellationRequested();
@@ -794,11 +792,8 @@ private async Task UpdateLazyPropertiesFromResultSetAsync(DbDataReader rs, int i
794792
return; // No lazy properties were loaded
795793
}
796794

797-
// Get the persister for the _subclass_
798-
var persister = instanceClass == rootPersister.EntityName
799-
? rootPersister
800-
: (ILoadable) Factory.GetEntityPersister(instanceClass);
801-
795+
var persister = await (GetConcretePersisterAsync(rs, i, rootPersister, key.Identifier, session, cancellationToken)).ConfigureAwait(false);
796+
var entry = optionalEntry ?? session.PersistenceContext.GetEntry(obj);
802797
// The property values will not be set when the entry status is Loading so in that case we have to get
803798
// the uninitialized lazy properties from the loaded state
804799
var uninitializedProperties = entry.Status == Status.Loading
@@ -822,7 +817,7 @@ private async Task UpdateLazyPropertiesFromResultSetAsync(DbDataReader rs, int i
822817
? EntityAliases[i].SuffixedPropertyAliases
823818
: GetSubclassEntityAliases(i, persister);
824819

825-
if (!await (persister.InitializeLazyPropertiesAsync(rs, id, obj, rootPersister, cols, updateLazyProperties, fetchAllProperties, session, cancellationToken)).ConfigureAwait(false))
820+
if (!await (persister.InitializeLazyPropertiesAsync(rs, id, obj, cols, updateLazyProperties, fetchAllProperties, session, cancellationToken)).ConfigureAwait(false))
826821
{
827822
return;
828823
}
@@ -882,18 +877,13 @@ internal static async Task UpdateCacheForEntityAsync(
882877
/// an array of "hydrated" values (do not resolve associations yet),
883878
/// and pass the hydrated state to the session.
884879
/// </summary>
885-
private async Task LoadFromResultSetAsync(DbDataReader rs, int i, object obj, string instanceClass, EntityKey key,
880+
private async Task LoadFromResultSetAsync(DbDataReader rs, int i, object obj, ILoadable persister, EntityKey key,
886881
LockMode lockMode, ILoadable rootPersister,
887882
ISessionImplementor session, CancellationToken cancellationToken)
888883
{
889884
cancellationToken.ThrowIfCancellationRequested();
890885
object id = key.Identifier;
891886

892-
// Get the persister for the _subclass_
893-
ILoadable persister = instanceClass == rootPersister.EntityName
894-
? rootPersister
895-
: (ILoadable) Factory.GetEntityPersister(instanceClass);
896-
897887
if (Log.IsDebugEnabled())
898888
{
899889
Log.Debug("Initializing object from DataReader: {0}", MessageHelper.InfoString(persister, id));
@@ -921,7 +911,7 @@ private async Task LoadFromResultSetAsync(DbDataReader rs, int i, object obj, st
921911
/// <summary>
922912
/// Determine the concrete class of an instance for the <c>DbDataReader</c>
923913
/// </summary>
924-
private async Task<string> GetInstanceClassAsync(DbDataReader rs, int i, ILoadable persister, object id, ISessionImplementor session, CancellationToken cancellationToken)
914+
private async Task<ILoadable> GetConcretePersisterAsync(DbDataReader rs, int i, ILoadable persister, object id, ISessionImplementor session, CancellationToken cancellationToken)
925915
{
926916
cancellationToken.ThrowIfCancellationRequested();
927917
if (persister.HasSubclasses)
@@ -939,9 +929,11 @@ private async Task<string> GetInstanceClassAsync(DbDataReader rs, int i, ILoadab
939929
persister.EntityName);
940930
}
941931

942-
return result;
932+
return persister.EntityName == result
933+
? persister
934+
: (ILoadable) Factory.GetEntityPersister(result);
943935
}
944-
return persister.EntityName;
936+
return persister;
945937
}
946938

947939
/// <summary>

src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public virtual Task BindValuesAsync(DbCommand ps, CancellationToken cancellation
6262
}
6363

6464
public Task InitializeLazyPropertiesAsync(
65-
DbDataReader rs, object id, object entity, ILoadable rootPersister, string[][] suffixedPropertyColumns,
65+
DbDataReader rs, object id, object entity, string[][] suffixedPropertyColumns,
6666
string[] uninitializedLazyProperties, bool allLazyProperties, ISessionImplementor session, CancellationToken cancellationToken)
6767
{
6868
if (!HasLazyProperties)

src/NHibernate/Async/Persister/Entity/ILoadable.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public static Task<object[]> HydrateAsync(
7373
/// </summary>
7474
//6.0 TODO: Change to void and merge into ILoadable
7575
internal static async Task<bool> InitializeLazyPropertiesAsync(
76-
this ILoadable loadable, DbDataReader rs, object id, object entity, ILoadable rootPersister, string[][] suffixedPropertyColumns,
76+
this ILoadable loadable, DbDataReader rs, object id, object entity, string[][] suffixedPropertyColumns,
7777
string[] uninitializedLazyProperties, bool allLazyProperties, ISessionImplementor session, CancellationToken cancellationToken)
7878
{
7979
cancellationToken.ThrowIfCancellationRequested();
@@ -83,7 +83,6 @@ internal static async Task<bool> InitializeLazyPropertiesAsync(
8383
rs,
8484
id,
8585
entity,
86-
rootPersister,
8786
suffixedPropertyColumns,
8887
uninitializedLazyProperties,
8988
allLazyProperties,

src/NHibernate/Engine/ISessionImplementor.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ namespace NHibernate.Engine
2121
// 6.0 TODO: Convert to interface methods, excepted SwitchCacheMode
2222
internal static partial class SessionImplementorExtensions
2323
{
24+
/// <summary>
25+
/// Instantiate the entity class, initializing with the given identifier
26+
/// </summary>
27+
internal static object Instantiate(this ISessionImplementor session, IEntityPersister persister, object id)
28+
{
29+
if(session is AbstractSessionImpl impl)
30+
return impl.Instantiate(persister, id);
31+
return session.Instantiate(persister.EntityName, id);
32+
}
33+
2434
internal static IDisposable BeginContext(this ISessionImplementor session)
2535
{
2636
if (session == null)
@@ -249,6 +259,8 @@ public partial interface ISessionImplementor
249259
/// </summary>
250260
object GetContextEntityIdentifier(object obj);
251261

262+
//Since 5.3
263+
//TODO 6.0 Remove (see SessionImplementorExtensions.Instantiate for replacement)
252264
/// <summary>
253265
/// Instantiate the entity class, initializing with the given identifier
254266
/// </summary>

src/NHibernate/Event/IEventSource.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public partial interface IEventSource : ISessionImplementor, ISession
1616
/// </summary>
1717
bool AutoFlushSuspended { get; }
1818

19+
//6.0 TODO Remove it (it's added directly to ISessionImplementor)
1920
/// <summary>
2021
/// Instantiate an entity instance, using either an interceptor,
2122
/// or the given persister

src/NHibernate/Impl/AbstractSessionImpl.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,19 @@ public IList ListFilter(object collection, IQueryExpression queryExpression, Que
192192
public abstract void FlushBeforeTransactionCompletion();
193193
public abstract void AfterTransactionCompletion(bool successful, ITransaction tx);
194194
public abstract object GetContextEntityIdentifier(object obj);
195+
196+
//Since 5.3
197+
[Obsolete("Use override with persister parameter")]
195198
public abstract object Instantiate(string clazz, object id);
196199

200+
//6.0 TODO: Make abstract
201+
public virtual object Instantiate(IEntityPersister persister, object id)
202+
{
203+
#pragma warning disable 618
204+
return Instantiate(persister.EntityName, id);
205+
#pragma warning restore 618
206+
}
207+
197208
public virtual IList List(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
198209
{
199210
using (BeginProcess())

src/NHibernate/Impl/SessionImpl.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ private IQueryExpressionPlan GetFilterQueryPlan(string role, bool shallow, strin
761761
: Factory.QueryPlanCache.GetFilterQueryPlan(filter, role, shallow, EnabledFilters);
762762
}
763763

764+
//Since 5.3
765+
[Obsolete("Use override with persister parameter")]
764766
public override object Instantiate(string clazz, object id)
765767
{
766768
using (BeginProcess())
@@ -785,7 +787,7 @@ public ActionQueue ActionQueue
785787
/// <param name="persister"></param>
786788
/// <param name="id"></param>
787789
/// <returns></returns>
788-
public object Instantiate(IEntityPersister persister, object id)
790+
public override object Instantiate(IEntityPersister persister, object id)
789791
{
790792
using (BeginProcess())
791793
{

src/NHibernate/Impl/StatelessSessionImpl.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,18 @@ public override object GetContextEntityIdentifier(object obj)
244244
}
245245
}
246246

247+
//Since 5.3
248+
[Obsolete("Use override with persister parameter")]
247249
public override object Instantiate(string clazz, object id)
250+
{
251+
return Instantiate(Factory.GetEntityPersister(clazz), id);
252+
}
253+
254+
public override object Instantiate(IEntityPersister persister, object id)
248255
{
249256
using (BeginProcess())
250257
{
251-
return Factory.GetEntityPersister(clazz).Instantiate(id);
258+
return persister.Instantiate(id);
252259
}
253260
}
254261

src/NHibernate/Loader/Loader.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,9 +1070,7 @@ private void InstanceAlreadyLoaded(DbDataReader rs, int i, ILoadable persister,
10701070
return;
10711071
}
10721072

1073-
var instanceClass = GetInstanceClass(rs, i, persister, key.Identifier, session);
1074-
entry = entry ?? session.PersistenceContext.GetEntry(obj);
1075-
UpdateLazyPropertiesFromResultSet(rs, i, obj, instanceClass, key, entry, persister, session, cacheBatchingHandler);
1073+
UpdateLazyPropertiesFromResultSet(rs, i, obj, key, entry, persister, session, cacheBatchingHandler);
10761074
}
10771075

10781076
private void CacheByUniqueKey(int i, IEntityPersister persister, object obj, ISessionImplementor session, bool alreadyLoaded)
@@ -1116,7 +1114,7 @@ private object InstanceNotYetLoaded(DbDataReader dr, int i, ILoadable persister,
11161114
{
11171115
object obj;
11181116

1119-
string instanceClass = GetInstanceClass(dr, i, persister, key.Identifier, session);
1117+
ILoadable concretePersister = GetConcretePersister(dr, i, persister, key.Identifier, session);
11201118

11211119
if (optionalObjectKey != null && key.Equals(optionalObjectKey))
11221120
{
@@ -1125,7 +1123,7 @@ private object InstanceNotYetLoaded(DbDataReader dr, int i, ILoadable persister,
11251123
}
11261124
else
11271125
{
1128-
obj = session.Instantiate(instanceClass, key.Identifier);
1126+
obj = session.Instantiate(concretePersister, key.Identifier);
11291127
}
11301128

11311129
// need to hydrate it
@@ -1134,7 +1132,7 @@ private object InstanceNotYetLoaded(DbDataReader dr, int i, ILoadable persister,
11341132
// (but don't yet initialize the object itself)
11351133
// note that we acquired LockMode.READ even if it was not requested
11361134
LockMode acquiredLockMode = lockMode == LockMode.None ? LockMode.Read : lockMode;
1137-
LoadFromResultSet(dr, i, obj, instanceClass, key, acquiredLockMode, persister, session);
1135+
LoadFromResultSet(dr, i, obj, concretePersister, key, acquiredLockMode, persister, session);
11381136

11391137
// materialize associations (and initialize the object) later
11401138
hydratedObjects.Add(obj);
@@ -1159,8 +1157,8 @@ private HashSet<string> GetFetchLazyProperties(int i)
11591157
return array?[i];
11601158
}
11611159

1162-
private void UpdateLazyPropertiesFromResultSet(DbDataReader rs, int i, object obj, string instanceClass, EntityKey key,
1163-
EntityEntry entry, ILoadable rootPersister, ISessionImplementor session,
1160+
private void UpdateLazyPropertiesFromResultSet(DbDataReader rs, int i, object obj, EntityKey key,
1161+
EntityEntry optionalEntry, ILoadable rootPersister, ISessionImplementor session,
11641162
Action<IEntityPersister, CachePutData> cacheBatchingHandler)
11651163
{
11661164
var fetchAllProperties = IsEagerPropertyFetchEnabled(i);
@@ -1171,11 +1169,8 @@ private void UpdateLazyPropertiesFromResultSet(DbDataReader rs, int i, object ob
11711169
return; // No lazy properties were loaded
11721170
}
11731171

1174-
// Get the persister for the _subclass_
1175-
var persister = instanceClass == rootPersister.EntityName
1176-
? rootPersister
1177-
: (ILoadable) Factory.GetEntityPersister(instanceClass);
1178-
1172+
var persister = GetConcretePersister(rs, i, rootPersister, key.Identifier, session);
1173+
var entry = optionalEntry ?? session.PersistenceContext.GetEntry(obj);
11791174
// The property values will not be set when the entry status is Loading so in that case we have to get
11801175
// the uninitialized lazy properties from the loaded state
11811176
var uninitializedProperties = entry.Status == Status.Loading
@@ -1199,7 +1194,7 @@ private void UpdateLazyPropertiesFromResultSet(DbDataReader rs, int i, object ob
11991194
? EntityAliases[i].SuffixedPropertyAliases
12001195
: GetSubclassEntityAliases(i, persister);
12011196

1202-
if (!persister.InitializeLazyProperties(rs, id, obj, rootPersister, cols, updateLazyProperties, fetchAllProperties, session))
1197+
if (!persister.InitializeLazyProperties(rs, id, obj, cols, updateLazyProperties, fetchAllProperties, session))
12031198
{
12041199
return;
12051200
}
@@ -1258,17 +1253,12 @@ internal static void UpdateCacheForEntity(
12581253
/// an array of "hydrated" values (do not resolve associations yet),
12591254
/// and pass the hydrated state to the session.
12601255
/// </summary>
1261-
private void LoadFromResultSet(DbDataReader rs, int i, object obj, string instanceClass, EntityKey key,
1256+
private void LoadFromResultSet(DbDataReader rs, int i, object obj, ILoadable persister, EntityKey key,
12621257
LockMode lockMode, ILoadable rootPersister,
12631258
ISessionImplementor session)
12641259
{
12651260
object id = key.Identifier;
12661261

1267-
// Get the persister for the _subclass_
1268-
ILoadable persister = instanceClass == rootPersister.EntityName
1269-
? rootPersister
1270-
: (ILoadable) Factory.GetEntityPersister(instanceClass);
1271-
12721262
if (Log.IsDebugEnabled())
12731263
{
12741264
Log.Debug("Initializing object from DataReader: {0}", MessageHelper.InfoString(persister, id));
@@ -1304,7 +1294,7 @@ private string[][] GetSubclassEntityAliases(int i, ILoadable persister)
13041294
/// <summary>
13051295
/// Determine the concrete class of an instance for the <c>DbDataReader</c>
13061296
/// </summary>
1307-
private string GetInstanceClass(DbDataReader rs, int i, ILoadable persister, object id, ISessionImplementor session)
1297+
private ILoadable GetConcretePersister(DbDataReader rs, int i, ILoadable persister, object id, ISessionImplementor session)
13081298
{
13091299
if (persister.HasSubclasses)
13101300
{
@@ -1321,9 +1311,11 @@ private string GetInstanceClass(DbDataReader rs, int i, ILoadable persister, obj
13211311
persister.EntityName);
13221312
}
13231313

1324-
return result;
1314+
return persister.EntityName == result
1315+
? persister
1316+
: (ILoadable) Factory.GetEntityPersister(result);
13251317
}
1326-
return persister.EntityName;
1318+
return persister;
13271319
}
13281320

13291321
/// <summary>

src/NHibernate/Persister/Entity/AbstractEntityPersister.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ public virtual object InitializeLazyProperty(string fieldName, object entity, IS
13951395
}
13961396

13971397
public void InitializeLazyProperties(
1398-
DbDataReader rs, object id, object entity, ILoadable rootPersister, string[][] suffixedPropertyColumns,
1398+
DbDataReader rs, object id, object entity, string[][] suffixedPropertyColumns,
13991399
string[] uninitializedLazyProperties, bool allLazyProperties, ISessionImplementor session)
14001400
{
14011401
if (!HasLazyProperties)

src/NHibernate/Persister/Entity/ILoadable.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public static object[] Hydrate(
107107
/// </summary>
108108
//6.0 TODO: Change to void and merge into ILoadable
109109
internal static bool InitializeLazyProperties(
110-
this ILoadable loadable, DbDataReader rs, object id, object entity, ILoadable rootPersister, string[][] suffixedPropertyColumns,
110+
this ILoadable loadable, DbDataReader rs, object id, object entity, string[][] suffixedPropertyColumns,
111111
string[] uninitializedLazyProperties, bool allLazyProperties, ISessionImplementor session)
112112
{
113113
if (loadable is AbstractEntityPersister abstractEntityPersister)
@@ -116,7 +116,6 @@ internal static bool InitializeLazyProperties(
116116
rs,
117117
id,
118118
entity,
119-
rootPersister,
120119
suffixedPropertyColumns,
121120
uninitializedLazyProperties,
122121
allLazyProperties,

0 commit comments

Comments
 (0)