|
1 | 1 |
|
| 2 | +using System; |
| 3 | +using System.Threading; |
| 4 | +using System.Threading.Tasks; |
2 | 5 | using NHibernate.Id;
|
3 | 6 | using NHibernate.Persister.Entity;
|
4 | 7 | using NHibernate.Proxy;
|
@@ -192,25 +195,37 @@ public static bool IsNotTransientSlow(string entityName, object entity, ISession
|
192 | 195 | /// </remarks>
|
193 | 196 | public static bool IsTransientSlow(string entityName, object entity, ISessionImplementor session)
|
194 | 197 | {
|
195 |
| - return IsTransientFast(entityName, entity, session) ?? |
196 |
| - HasDbSnapshot(entityName, entity, session); |
| 198 | + bool? isTransient = IsTransientFast(entityName, entity, session); |
| 199 | + if (isTransient.HasValue) |
| 200 | + return isTransient.Value; |
| 201 | + |
| 202 | + var persister = session.GetEntityPersister(entityName, entity); |
| 203 | + var id = persister.GetIdentifier(entity); |
| 204 | + |
| 205 | + // check to see if it is in the second-level cache |
| 206 | + if (persister.HasCache && session.CacheMode.HasFlag(CacheMode.Get)) |
| 207 | + { |
| 208 | + var ck = session.GenerateCacheKey(id, persister.IdentifierType, persister.RootEntityName); |
| 209 | + if (persister.Cache.Get(ck, session.Timestamp) != null) |
| 210 | + return false; |
| 211 | + } |
| 212 | + |
| 213 | + return HasDbSnapshot(persister, id, session); |
197 | 214 | }
|
198 | 215 |
|
199 |
| - static bool HasDbSnapshot(string entityName, object entity, ISessionImplementor session) |
| 216 | + static bool HasDbSnapshot(IEntityPersister persister, object identifier, ISessionImplementor session) |
200 | 217 | {
|
201 |
| - IEntityPersister persister = session.GetEntityPersister(entityName, entity); |
202 | 218 | if (persister.IdentifierGenerator is Assigned)
|
203 | 219 | {
|
204 | 220 | // When using assigned identifiers we cannot tell if an entity
|
205 | 221 | // is transient or detached without querying the database.
|
206 | 222 | // This could potentially cause Select N+1 in cascaded saves, so warn the user.
|
207 | 223 | log.Warn("Unable to determine if {0} with assigned identifier {1} is transient or detached; querying the database. Use explicit Save() or Update() in session to prevent this.",
|
208 |
| - entity, persister.GetIdentifier(entity)); |
| 224 | + persister.EntityName, identifier); |
209 | 225 | }
|
210 | 226 |
|
211 | 227 | // hit the database, after checking the session cache for a snapshot
|
212 |
| - System.Object[] snapshot = |
213 |
| - session.PersistenceContext.GetDatabaseSnapshot(persister.GetIdentifier(entity), persister); |
| 228 | + System.Object[] snapshot = session.PersistenceContext.GetDatabaseSnapshot(identifier, persister); |
214 | 229 | return snapshot == null;
|
215 | 230 | }
|
216 | 231 |
|
|
0 commit comments