protected virtual bool HandleInterception(FlushEntityEvent @event) { ISessionImplementor session = @event.Session; EntityEntry entry = @event.EntityEntry; IEntityPersister persister = entry.Persister; object entity = @event.Entity; //give the Interceptor a chance to modify property values object[] values = @event.PropertyValues; bool intercepted = InvokeInterceptor(session, entity, entry, values, persister); //now we might need to recalculate the dirtyProperties array if (intercepted && @event.DirtyCheckPossible && [email protected]) { int[] dirtyProperties; if (@event.HasDatabaseSnapshot) { dirtyProperties = persister.FindModified(@event.DatabaseSnapshot, values, entity, session); } else { dirtyProperties = persister.FindDirty(values, entry.LoadedState, entity, session); } @event.DirtyProperties = dirtyProperties; } return(intercepted); }
/// <summary> Perform a dirty check, and attach the results to the event</summary> protected virtual void DirtyCheck(FlushEntityEvent @event) { object entity = @event.Entity; object[] values = @event.PropertyValues; ISessionImplementor session = @event.Session; EntityEntry entry = @event.EntityEntry; IEntityPersister persister = entry.Persister; object id = entry.Id; object[] loadedState = entry.LoadedState; int[] dirtyProperties = session.Interceptor.FindDirty(entity, id, values, loadedState, persister.PropertyNames, persister.PropertyTypes); @event.DatabaseSnapshot = null; bool interceptorHandledDirtyCheck; bool cannotDirtyCheck; if (dirtyProperties == null) { // Interceptor returned null, so do the dirtycheck ourself, if possible interceptorHandledDirtyCheck = false; cannotDirtyCheck = loadedState == null; // object loaded by update() if (!cannotDirtyCheck) { // dirty check against the usual snapshot of the entity dirtyProperties = persister.FindDirty(values, loadedState, entity, session); } else { // dirty check against the database snapshot, if possible/necessary object[] databaseSnapshot = GetDatabaseSnapshot(session, persister, id); if (databaseSnapshot != null) { dirtyProperties = persister.FindModified(databaseSnapshot, values, entity, session); cannotDirtyCheck = false; @event.DatabaseSnapshot = databaseSnapshot; } } } else { // the Interceptor handled the dirty checking cannotDirtyCheck = false; interceptorHandledDirtyCheck = true; } @event.DirtyProperties = dirtyProperties; @event.DirtyCheckHandledByInterceptor = interceptorHandledDirtyCheck; @event.DirtyCheckPossible = !cannotDirtyCheck; }
/// <summary> Perform a dirty check, and attach the results to the event</summary> protected virtual void DirtyCheck(FlushEntityEvent @event) { object entity = @event.Entity; object[] values = @event.PropertyValues; ISessionImplementor session = @event.Session; EntityEntry entry = @event.EntityEntry; IEntityPersister persister = entry.Persister; object id = entry.Id; object[] loadedState = entry.LoadedState; int[] dirtyProperties = session.Interceptor.FindDirty(entity, id, values, loadedState, persister.PropertyNames, persister.PropertyTypes); @event.DatabaseSnapshot = null; bool interceptorHandledDirtyCheck; bool cannotDirtyCheck; if (dirtyProperties == null) { // Interceptor returned null, so do the dirtycheck ourself, if possible interceptorHandledDirtyCheck = false; cannotDirtyCheck = loadedState == null; // object loaded by update() if (!cannotDirtyCheck) { // dirty check against the usual snapshot of the entity dirtyProperties = persister.FindDirty(values, loadedState, entity, session); } else if (entry.Status == Status.Deleted && [email protected]()) { // A non-modifiable (e.g., read-only or immutable) entity needs to be have // references to transient entities set to null before being deleted. No other // fields should be updated. if (values != entry.DeletedState) { throw new InvalidOperationException("Entity has status Status.Deleted but values != entry.DeletedState"); } // Even if loadedState == null, we can dirty-check by comparing currentState and // entry.getDeletedState() because the only fields to be updated are those that // refer to transient entities that are being set to null. // - currentState contains the entity's current property values. // - entry.getDeletedState() contains the entity's current property values with // references to transient entities set to null. // - dirtyProperties will only contain properties that refer to transient entities object[] currentState = persister.GetPropertyValues(@event.Entity); dirtyProperties = persister.FindDirty(entry.DeletedState, currentState, entity, session); cannotDirtyCheck = false; } else { // dirty check against the database snapshot, if possible/necessary object[] databaseSnapshot = GetDatabaseSnapshot(session, persister, id); if (databaseSnapshot != null) { dirtyProperties = persister.FindModified(databaseSnapshot, values, entity, session); cannotDirtyCheck = false; @event.DatabaseSnapshot = databaseSnapshot; } } } else { // the Interceptor handled the dirty checking cannotDirtyCheck = false; interceptorHandledDirtyCheck = true; } @event.DirtyProperties = dirtyProperties; @event.DirtyCheckHandledByInterceptor = interceptorHandledDirtyCheck; @event.DirtyCheckPossible = !cannotDirtyCheck; }