It is not possible to revert to a copy as retained by the cache because the
cache does not have a separate copy. NHibernate only tracks whether an
object has been changed and if it has then it must be persisted or evicted.
The only way to get the original object back in cache is to reread the
database.

You may wish it were otherwise, expect it were otherwise, but it is not so.

John Davidson

On Tue, May 4, 2010 at 2:49 PM, tz <[email protected]>wrote:

> "Revert changes with the state of my first load" is what the user
> thinks when she has changed an entity, but regrets. Thus wants to
> cancel. However, she doesn't want to be punished by another database
> hit. I'm sure many other people decide in this case to start a new
> session or evict the object graph and get it again. All to me sound
> like a half-baked solution for reasons I've mentioned before. Another
> half-baked solution is to say that you only change the entities once
> you're 100% sure (no, I want to "commit" once I'm 100% sure).
>
> Having said all this, what I want to reach here, completely fits in
> how I want my application to work. I think it is compatible with UoW
> and all those other fancy design patterns. This is clearly a missing
> feature to me. Therefore, I was really hoping for a technical
> satisfying answer, rather than advocating that I'm doing is something
> which is not written in one of the tutorials.
>
> So, please... does anyone know how I could do this trick of reverting
> changes in a graph?
>
> On May 4, 7:32 pm, Fabio Maulo <[email protected]> wrote:
> > There is something saying me that your problem is in another place.
> > "Revert changes with the state of my first load"..... mmmmm
> >
> > On Tue, May 4, 2010 at 3:05 PM, tz <[email protected]
> >wrote:
> >
> > > Thanks for confirming that. I silently started guessing that the
> > > Refresh method shouldn't be what I should use. I started writing my
> > > own "RevertChanges" on a graph, but I'm stuck on how to evict
> > > collections (plus the attached pending deletes/adds). See my code
> > > below:
> >
> > >    public static class ISessionExtensions
> > >    {
> > >        public static void RevertChanges(this ISession session, object
> > > obj)
> > >        {
> > >            var source = session as IEventSource;
> > >            var action = new RevertChangesCascadingAction();
> >
> > >            action.RevertChanges(source, obj);
> > >        }
> >
> > >        private class RevertChangesCascadingAction : CascadingAction
> > >        {
> > >            public override void Cascade(IEventSource session, object
> > > child, string entityName, object anything, bool
> > > isCascadeDeleteEnabled)
> > >            {
> > >                DoRevert(session, child);
> > >            }
> > >            public override IEnumerable
> > > GetCascadableChildrenIterator(IEventSource session, CollectionType
> > > collectionType, object collection)
> > >            {
> > >                var coll = collection as
> > > NHibernate.Collection.IPersistentCollection;
> > >                var collectionEntry =
> > > session.PersistenceContext.GetCollectionEntry(coll);
> >
> > >                // TODO: HELP!!!
> > >                //session.Evict(collection);
> > >                //collectionEntry.LoadedPersister.Recreate(coll,
> > > collectionEntry.LoadedKey, session);
> >
> > >                // evicts don't cascade to uninitialized collections
> > >                return GetLoadedElementsIterator(session,
> > > collectionType, collection);
> > >            }
> > >            public override bool DeleteOrphans
> > >            {
> > >                get { return false; }
> > >            }
> > >            public override bool PerformOnLazyProperty
> > >            {
> > >                get { return false; }
> > >            }
> >
> > >            protected void DoRevert(IEventSource session, object obj)
> > >            {
> > >                EntityEntry entityEntry = GetEntityEntry(session,
> > > obj);
> >
> > >                IEntityPersister persister = entityEntry.Persister;
> > >                EntityMode mode = persister.GuessEntityMode(obj) ??
> > > EntityMode.Poco;
> > >                persister.SetPropertyValues(obj,
> > > entityEntry.LoadedState, mode);
> > >            }
> >
> > >            protected EntityEntry GetEntityEntry(IEventSource session,
> > > object obj)
> > >            {
> > >                IPersistenceContext context =
> > > session.PersistenceContext;
> >
> > >                if (obj is ValueType)
> > >                    return null;
> >
> > >                if (context.IsEntryFor(obj) == false)
> > >                    return null;
> >
> > >                EntityEntry entityEntry = context.GetEntry(obj);
> > >                return entityEntry;
> > >            }
> >
> > >            public void RevertChanges(IEventSource session, object
> > > obj)
> > >            {
> > >                EntityEntry entityEntry = GetEntityEntry(session,
> > > obj);
> >
> > >                DoRevert(session, obj);
> >
> > >                session.PersistenceContext.IncrementCascadeLevel();
> > >                try
> > >                {
> > >                    new Cascade(this, CascadePoint.AfterUpdate,
> > > session).CascadeOn(entityEntry.Persister, obj);
> > >                }
> > >                finally
> > >                {
> >
> > > session.PersistenceContext.DecrementCascadeLevel();
> > >                 }
> > >            }
> > >        }
> > >    }
> >
> > > On Apr 30, 7:55 pm, Jason Dentler <[email protected]> wrote:
> > > > Confirmed it with Fabio: "Refresh is an explicit hit to DB"
> >
> > > > On Fri, Apr 30, 2010 at 8:35 AM, tz <
> > > [email protected]>wrote:
> >
> > > > > * Transaction over a read didn't help (see reply on Jason Dentler)
> > > > > * Second level cache is for sharing data across transactions
> >
> > > > > On Apr 30, 12:24 pm, John Davidson <[email protected]> wrote:
> > > > > > It does not matter what the UoW pattern says about data read. You
> > > > > _REALLY_
> > > > > > need to put a read action in a NHibernate transaction if you want
> to
> > > > > improve
> > > > > > performance. Not having your reads in a transaction may be why
> you
> > > need a
> > > > > > second level cache (to compensate for not following the specified
> > > rules).
> > > > > > Most of the transactional databases now wrap a read action in an
> ACID
> > > > > > transaction on their own, if the request is not already in a
> > > transaction
> > > > > -
> > > > > > this activity by the database takes more time and resource than
> if it
> > > is
> > > > > > done in the application with NHibernate and UoW.
> >
> > > > > > John Davidson
> >
> > > > > > On Fri, Apr 30, 2010 at 7:14 AM, tz <
> > > > > [email protected]>wrote:
> >
> > > > > > > Thanks for the reply. See my comments inline
> >
> > > > > > > On Apr 29, 8:26 pm, Jason Meckley <[email protected]>
> wrote:
> > > > > > > > I would approach the problem in a completely different
> manner.
> > > > > > > > 1. no long running sessions
> > > > > > > > 2. only use 2nd level cache in edge cases as a last resort
> > > > > > > > 3. for multi-step operations/commands I would use an
> intermediate
> > > DTO
> > > > > > > > to store updates. When the user clicks "save" is when i would
> > > alter
> > > > > > > > the domain objects. this makes undoing changes much easier.
> > > simply
> > > > > > > > abandon the DTO.
> >
> > > > > > > I'm not sure whether you do understand my question, but I can't
> > > relate
> > > > > > > any of your reply to my question. I also don't agree with what
> > > you're
> > > > > > > saying...
> > > > > > > * I don't know what "no long running sessions" would solve for
> my
> > > > > > > issue. All these things you're proposing are a "very complex"
> way
> > > to
> > > > > > > do Evict/Load on the same session.
> > > > > > > * 2nd level cache is for performance reasons. The issue I'm
> posting
> > > > > > > about is also for performance reasons. So, this cache stays
> > > > > > > * Why would I do any object dirty management myself, if
> nHibernate
> > > can
> > > > > > > do it for me.
> >
> > > > > > > > if you do continue down this path are all your session calls
> > > > > happening
> > > > > > > > within a transaction? Proper use of NH dictates that all
> > > operations,
> > > > > > > > both read and write, should happen within at transaction.
> This is
> > > > > > > > critical for client POIDs, proper UOW management and 2nd
> level
> > > cache.
> >
> > > > > > > Again, no answer on my question. Even more, I don't agree with
> > > you...
> > > > > > > * UoW pattern doesn't say that a read should be in a ACID
> > > transaction.
> > > > > > > UoW itself is a "business transaction" implementation, which is
> > > based
> > > > > > > optimistic concurrency ideologies (meaning that you shouldn't
> keep
> > > an
> > > > > > > ACID transaction open between the reads and the writes).
> >
> > > > > > > What I want is simply a Update() which does what Evict/Load
> does,
> > > but
> > > > > > > not with giving me a new instance. That's all I'd want to know.
> I
> > > know
> > > > > > > nH keeps the original state in the session (and the second
> level
> > > > > > > cache), so it shouldn't be that difficult I assume.
> >
> > > > > > > > On Apr 29, 2:05 pm, tz <[email protected]
> >
> > > wrote:
> >
> > > > > > > > > Hi guys,
> >
> > > > > > > > > I'm working with a long running session which contains all
> my
> > > > > required
> > > > > > > > > data. Further, I use level 2 cache intensively, to cache
> that
> > > > > > > > > information. I let my user edit this data directly using UI
> > > > > controls.
> >
> > > > > > > > > The user can decide to cancel the modifications, which I
> though
> > > I'd
> > > > > > > > > easily solve with performing a ISession.Refresh(..) on the
> > > > > aggregate
> > > > > > > > > root of the changed entity.
> >
> > > > > > > > > However, it turns out that Refresh(...) always goes to the
> > > database
> > > > > to
> > > > > > > > > refetch the data, even if the data is available in second
> level
> > > > > cache
> > > > > > > > > (tested that the data is there using a second ISession,
> which
> > > > > returned
> > > > > > > > > the data without a database hit).
> >
> > > > > > > > > Is there a way to refresh entity from data in the second
> level
> > > > > cache?
> >
> > > > > > > > > I don't want to use Evict+Load, as I will then get a new
> > > instance
> > > > > > > > > (Refresh(...) updates the same instance).
> >
> > > > > > > > > Thanks
> >
> > > > > > > > > --
> > > > > > > > > You received this message because you are subscribed to the
> > > Google
> > > > > > > Groups "nhusers" group.
> > > > > > > > > To post to this group, send email to
> [email protected].
> > > > > > > > > To unsubscribe from this group, send email to
> > > > > > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > ­>
> > > > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > <nhusers%252bunsubscr...@googlegroup­s.com>
> > > > > ­>
> > > > > > > .
> > > > > > > > > For more options, visit this group athttp://
> > > > > > > groups.google.com/group/nhusers?hl=en.
> >
> > > > > > > > --
> > > > > > > > You received this message because you are subscribed to the
> > > Google
> > > > > Groups
> > > > > > > "nhusers" group.
> > > > > > > > To post to this group, send email to
> [email protected].
> > > > > > > > To unsubscribe from this group, send email to
> > > > > > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > ­>
> > > > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > <nhusers%252bunsubscr...@googlegroup­s.com>
> > > > > ­>
> > > > > > > .
> > > > > > > > For more options, visit this group athttp://
> > > > > > > groups.google.com/group/nhusers?hl=en.- Hide quoted text -
> >
> > > > > > > > - Show quoted text -
> >
> > > > > > > --
> > > > > > > You received this message because you are subscribed to the
> Google
> > > > > Groups
> > > > > > > "nhusers" group.
> > > > > > > To post to this group, send email to [email protected].
> > > > > > > To unsubscribe from this group, send email to
> > > > > > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > ­>
> > > > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > <nhusers%252bunsubscr...@googlegroup­s.com>
> > > > > ­>
> > > > > > > .
> > > > > > > For more options, visit this group at
> > > > > > >http://groups.google.com/group/nhusers?hl=en.
> >
> > > > > > --
> > > > > > You received this message because you are subscribed to the
> Google
> > > Groups
> > > > > "nhusers" group.
> > > > > > To post to this group, send email to [email protected].
> > > > > > To unsubscribe from this group, send email to
> > > > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > ­>
> > > > > .
> > > > > > For more options, visit this group athttp://
> > > > > groups.google.com/group/nhusers?hl=en.- Hide quoted text -
> >
> > > > > > - Show quoted text -
> >
> > > > > --
> > > > > You received this message because you are subscribed to the Google
> > > Groups
> > > > > "nhusers" group.
> > > > > To post to this group, send email to [email protected].
> > > > > To unsubscribe from this group, send email to
> > > > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > <nhusers%[email protected]<nhusers%[email protected]>
> <nhusers%252bunsubscr...@googlegroup­s.com>
> > > ­>
> > > > > .
> > > > > For more options, visit this group at
> > > > >http://groups.google.com/group/nhusers?hl=en.
> >
> > > > --
> > > > You received this message because you are subscribed to the Google
> Groups
> > > "nhusers" group.
> > > > To post to this group, send email to [email protected].
> > > > To unsubscribe from this group, send email to
> > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > .
> > > > For more options, visit this group athttp://
> > > groups.google.com/group/nhusers?hl=en.- Hide quoted text -
> >
> > > > - Show quoted text -
> >
> > > --
> > > You received this message because you are subscribed to the Google
> Groups
> > > "nhusers" group.
> > > To post to this group, send email to [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected]<nhusers%[email protected]>
> <nhusers%[email protected]<nhusers%[email protected]>
> ­>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/nhusers?hl=en.
> >
> > --
> > Fabio Maulo
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> [email protected]<nhusers%[email protected]>
> .
> > For more options, visit this group athttp://
> groups.google.com/group/nhusers?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<nhusers%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to