Skip to content

Commit 06c998b

Browse files
committed
Refactor ForeignKeys.IsTransient & ForeignKeys.IsNotTransient to reduce async code generation
1 parent 0c4507d commit 06c998b

File tree

8 files changed

+40
-36
lines changed

8 files changed

+40
-36
lines changed

src/NHibernate/Collection/AbstractPersistentCollection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ protected virtual ICollection GetOrphans(ICollection oldElements, ICollection cu
714714
var currentIds = new HashSet<TypedValue>();
715715
foreach (object current in currentElements)
716716
{
717-
if (current != null && ForeignKeys.IsNotTransient(entityName, current, null, session))
717+
if (current != null && ForeignKeys.IsNotTransientSlow(entityName, current, session))
718718
{
719719
object currentId = ForeignKeys.GetEntityIdentifierIfNotUnsaved(entityName, current, session);
720720
currentIds.Add(new TypedValue(idType, currentId));
@@ -736,7 +736,7 @@ protected virtual ICollection GetOrphans(ICollection oldElements, ICollection cu
736736

737737
public void IdentityRemove(IList list, object obj, string entityName, ISessionImplementor session)
738738
{
739-
if (obj != null && ForeignKeys.IsNotTransient(entityName, obj, null, session))
739+
if (obj != null && ForeignKeys.IsNotTransientSlow(entityName, obj, session))
740740
{
741741
IType idType = session.Factory.GetEntityPersister(entityName).IdentifierType;
742742

src/NHibernate/Engine/CascadingAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ public override void NoCascade(IEventSource session, object child, object parent
343343
{
344344
string childEntityName = ((EntityType)type).GetAssociatedEntityName(session.Factory);
345345

346-
if (!IsInManagedState(child, session) && !(child.IsProxy()) && ForeignKeys.IsTransient(childEntityName, child, null, session))
346+
if (!IsInManagedState(child, session) && !child.IsProxy() && ForeignKeys.IsTransientSlow(childEntityName, child, session))
347347
{
348348
string parentEntiytName = persister.EntityName;
349349
string propertyName = persister.PropertyNames[propertyIndex];

src/NHibernate/Engine/ForeignKeys.cs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private bool IsNullifiable(string entityName, object obj)
138138
EntityEntry entityEntry = session.PersistenceContext.GetEntry(obj);
139139
if (entityEntry == null)
140140
{
141-
return IsTransient(entityName, obj, null, session);
141+
return IsTransientSlow(entityName, obj, session);
142142
}
143143
else
144144
{
@@ -151,31 +151,25 @@ private bool IsNullifiable(string entityName, object obj)
151151
/// Is this instance persistent or detached?
152152
/// </summary>
153153
/// <remarks>
154-
/// If <paramref name="assumed"/> is non-null, don't hit the database to make the
155-
/// determination, instead assume that value; the client code must be
156-
/// prepared to "recover" in the case that this assumed result is incorrect.
154+
/// Hit the database to make the determination.
157155
/// </remarks>
158-
public static bool IsNotTransient(string entityName, System.Object entity, bool? assumed, ISessionImplementor session)
156+
public static bool IsNotTransientSlow(string entityName, object entity, ISessionImplementor session)
159157
{
160158
if (entity.IsProxy())
161159
return true;
162160
if (session.PersistenceContext.IsEntryFor(entity))
163161
return true;
164-
return !IsTransient(entityName, entity, assumed, session);
162+
return !IsTransientSlow(entityName, entity, session);
165163
}
166164

167165
/// <summary>
168166
/// Is this instance, which we know is not persistent, actually transient?
169-
/// If <tt>assumed</tt> is non-null, don't hit the database to make the
170-
/// determination, instead assume that value; the client code must be
171-
/// prepared to "recover" in the case that this assumed result is incorrect.
167+
/// Don't hit the database to make the determination, instead return null;
172168
/// </summary>
173169
/// <remarks>
174-
/// If <paramref name="assumed"/> is non-null, don't hit the database to make the
175-
/// determination, instead assume that value; the client code must be
176-
/// prepared to "recover" in the case that this assumed result is incorrect.
170+
/// Don't hit the database to make the determination, instead return null;
177171
/// </remarks>
178-
public static bool IsTransient(string entityName, object entity, bool? assumed, ISessionImplementor session)
172+
public static bool? IsTransientFast(string entityName, object entity, ISessionImplementor session)
179173
{
180174
if (Equals(Intercept.LazyPropertyInitializer.UnfetchedProperty, entity))
181175
{
@@ -185,27 +179,33 @@ public static bool IsTransient(string entityName, object entity, bool? assumed,
185179
}
186180

187181
// let the interceptor inspect the instance to decide
188-
bool? isUnsaved = session.Interceptor.IsTransient(entity);
189-
if (isUnsaved.HasValue)
190-
return isUnsaved.Value;
191-
192182
// let the persister inspect the instance to decide
193-
IEntityPersister persister = session.GetEntityPersister(entityName, entity);
194-
isUnsaved = persister.IsTransient(entity, session);
195-
if (isUnsaved.HasValue)
196-
return isUnsaved.Value;
183+
return session.Interceptor.IsTransient(entity) ??
184+
session.GetEntityPersister(entityName, entity).IsTransient(entity, session);
185+
}
197186

198-
// we use the assumed value, if there is one, to avoid hitting
199-
// the database
200-
if (assumed.HasValue)
201-
return assumed.Value;
187+
/// <summary>
188+
/// Is this instance, which we know is not persistent, actually transient?
189+
/// </summary>
190+
/// <remarks>
191+
/// Hit the database to make the determination.
192+
/// </remarks>
193+
public static bool IsTransientSlow(string entityName, object entity, ISessionImplementor session)
194+
{
195+
return IsTransientFast(entityName, entity, session) ??
196+
HasDbSnapshot(entityName, entity, session);
197+
}
202198

199+
static bool HasDbSnapshot(string entityName, object entity, ISessionImplementor session)
200+
{
201+
IEntityPersister persister = session.GetEntityPersister(entityName, entity);
203202
if (persister.IdentifierGenerator is Assigned)
204203
{
205204
// When using assigned identifiers we cannot tell if an entity
206205
// is transient or detached without querying the database.
207206
// This could potentially cause Select N+1 in cascaded saves, so warn the user.
208-
log.Warn("Unable to determine if " + entity.ToString()
207+
log.Warn(
208+
"Unable to determine if " + entity.ToString()
209209
+ " with assigned identifier " + persister.GetIdentifier(entity)
210210
+ " is transient or detached; querying the database."
211211
+ " Use explicit Save() or Update() in session to prevent this.");
@@ -247,7 +247,7 @@ public static object GetEntityIdentifierIfNotUnsaved(string entityName, object e
247247
return entity;
248248
/**********************************************/
249249

250-
if (IsTransient(entityName, entity, false, session))
250+
if (IsTransientFast(entityName, entity, session).GetValueOrDefault())
251251
{
252252
/***********************************************/
253253
// TODO NH verify the behavior of NH607 test

src/NHibernate/Event/Default/AbstractSaveEventListener.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,10 @@ protected virtual EntityState GetEntityState(object entity, string entityName, E
422422
//the object is transient or detached
423423
//the entity is not associated with the session, so
424424
//try interceptor and unsaved-value
425-
if (ForeignKeys.IsTransient(entityName, entity, AssumedUnsaved, source))
425+
var assumed = AssumedUnsaved;
426+
if (assumed.HasValue
427+
? ForeignKeys.IsTransientFast(entityName, entity, source).GetValueOrDefault(assumed.Value)
428+
: ForeignKeys.IsTransientSlow(entityName, entity, source))
426429
{
427430
if (log.IsDebugEnabled)
428431
{

src/NHibernate/Event/Default/DefaultDeleteEventListener.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public virtual void OnDelete(DeleteEvent @event, ISet<object> transientEntities)
4545
log.Debug("entity was not persistent in delete processing");
4646

4747
persister = source.GetEntityPersister(@event.EntityName, entity);
48-
49-
if (ForeignKeys.IsTransient(persister.EntityName, entity, null, source))
48+
49+
if (ForeignKeys.IsTransientSlow(persister.EntityName, entity, source))
5050
{
5151
DeleteTransientEntity(source, entity, @event.CascadeDeleteEnabled, persister, transientEntities);
5252
// EARLY EXIT!!!

src/NHibernate/Event/Default/DefaultLockEventListener.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using NHibernate.Engine;
33
using NHibernate.Persister.Entity;
4+
using NHibernate.Proxy;
45

56
namespace NHibernate.Event.Default
67
{
@@ -42,7 +43,7 @@ public virtual void OnLock(LockEvent @event)
4243
{
4344
IEntityPersister persister = source.GetEntityPersister(@event.EntityName, entity);
4445
object id = persister.GetIdentifier(entity);
45-
if (!ForeignKeys.IsNotTransient(@event.EntityName, entity, false, source))
46+
if (ForeignKeys.IsTransientFast(@event.EntityName, entity, source).GetValueOrDefault())
4647
{
4748
throw new TransientObjectException("cannot lock an unsaved transient instance: " + persister.EntityName);
4849
}

src/NHibernate/Event/Default/DefaultRefreshEventListener.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public virtual void OnRefresh(RefreshEvent @event, IDictionary refreshedAlready)
118118

119119
// NH Different behavior : we are ignoring transient entities without throw any kind of exception
120120
// because a transient entity is "self refreshed"
121-
if (!ForeignKeys.IsTransient(persister.EntityName, obj, result == null, @event.Session))
121+
if (!ForeignKeys.IsTransientFast(persister.EntityName, obj, @event.Session).GetValueOrDefault(result == null))
122122
UnresolvableObjectException.ThrowIfNull(result, id, persister.EntityName);
123123
}
124124

src/NHibernate/Type/EntityType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public override object Replace(object original, object target, ISessionImplement
239239
{
240240
return target;
241241
}
242-
if (session.GetContextEntityIdentifier(original) == null && ForeignKeys.IsTransient(associatedEntityName, original, false, session))
242+
if (session.GetContextEntityIdentifier(original) == null && ForeignKeys.IsTransientFast(associatedEntityName, original, session).GetValueOrDefault())
243243
{
244244
object copy = session.Factory.GetEntityPersister(associatedEntityName).Instantiate(null);
245245
//TODO: should this be Session.instantiate(Persister, ...)?

0 commit comments

Comments
 (0)