Thanks for that, Diego. I think this is coming closer to what I want.

In fact, we've started developing our own IEditableObject
implementation, but soon realised that we needed a "special" for
handling collections. Another thing was also to let nHibernate know
that we have reverted the change. nHibernate seems to keep sql-
statements-to-be-executed-on-commit in a kind of a ActionQueue, which
needs to know about your cancelations as well.

But as I said, those were issues with our own version... I'll have a
look at this implementation, this one might have though about those
special cases much more.

On May 5, 7:12 pm, Diego Mijelshon <[email protected]> wrote:
> unhaddins has an implementation of IEditableObject for your entities using
> Castle. Maybe that's what you're looking for.
>
>    Diego
>
> On Tue, May 4, 2010 at 17:43, tz <[email protected]>wrote:
>
>
>
> > I'm not asking myself that question.... obviously nH still has
> > releases scheduled, so there must be missing functionality.
>
> > Sure,
>
> > Architecture:
> > - A Winforms; one tier application; layered architecture, based on DDD
> > principles
> > - Session management is one-to-one with UoW. In fact, UoW is simply a
> > wrapper around nH Session. UoW is per use-case basis
>
> > Use-case:
> > - A typical use-case consists of a list panel and a details panel,
> > both displayed on the same window; they both share the same UoW;
> > - A use-case starts with displaying a list of entities (in DDD terms:
> > only the aggregate-root entities);
> > - The user can choose to modify one of the entities by loading its
> > details into the screen;
> > - After having modified something in the aggregate, the user can
> > decide to discard the change or commit the change made to the
> > aggregate;
>
> > Decisions:
> > - UoW is used for change tracking. I don't want to do my own dirty
> > checking myself, as nH does a better job.
> > - UoW is used as a "business transaction" principle, the way described
> > by Martin Fowler. Meaning that the UoW needs to know about "any"
> > proposed change. I don't even want to do any change queueing
> > management, as again nH does a better job.
> > - I continue using the same UoW for the lifetime of the "entities
> > list". Sometimes, this is equal to application-lifetime. I'm not
> > concerned with my UoW becoming a giant collection, as the user's data
> > scope-set is limited.
> > - When the user discards the applied modifications, I don't want to
> > evict the aggregate-roots and reload them; I don't want a new
> > instance, I want the current instance being reverted to an initial
> > state. Reason being is that 1) I think that's much cleaner; 2) that's
> > how nH does it with the Refresh(...) already; 3) I don't need to
> > reload all my lists from the UoW in order to guarantee that all my
> > instances are actually attached to the UoW I'm using.
> > -
>
> > On May 4, 8:47 pm, Fabio Maulo <[email protected]> wrote:
> > > by side, the other thought would be: why within ~6 years of NH and  ~9 of
> > > Hibernate with hundred of thousand applications using both frameworks,
> > > nobody needs a such feature ?
>
> > > That is only my thought each time I'm thinking about a new feature in NH.
>
> > > About revert:
> > > Which kind of application are you implementing ?
> > > WinForms, WebForms, WPF, MVC, WCF ? (for sure no REST)
> > > How you are managing the session ?
> > > Why you are changing the state of an entity inside the session if the
> > > modification was not confirmed by user ?
> > > and so on....
>
> > > On Tue, May 4, 2010 at 4:35 PM, tz <[email protected]
> > >wrote:
>
> > > > Interesting question, and the answer is; yes, I have though about it
> > > > very well, and my conclusion is still that there are soo many similar
> > > > features in (n)Hibernate to what I want, that with a little bit of
> > > > help from an insider with more "architectural knowledge of
> > > > (n)Hibernate", this feature should be small in code. "small" when you
> > > > know the inside of the product...
>
> > > > On May 4, 8:18 pm, Carlos cubas <[email protected]> wrote:
> > > > > tz, have you considered that, maybe just maybe, you are swimming in
> > the
> > > > wrong direction? by yourself?
>
> > > > > -Carlos
>
> > > > > Practice makes perfect, but if no one is perfect, why practice?
>
> > > > > > Date: Tue, 4 May 2010 11:49:35 -0700
> > > > > > Subject: [nhusers] Re: Refresh from second level cache
> > > > > > From: [email protected]
> > > > > > To: [email protected]
>
> > > > > > "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();
> > > > > > > >                 }
> > > > > > > >            }
>
> ...
>
> read more »- 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].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to