I understand your scenario, but there's nothing preventing you from copying
the object into a temp, so that you can still rely on business rules, and
then try to copy the temp into the real object when the user clicks "ok".
There's no real need to modify the "real" object,and deal with eviction,
restoring, whatever, while the user is changing values in the editor.

On Tue, May 4, 2010 at 4:43 PM, 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();
> > > > > > >                 }
> > > > > > >            }
> > > > > > >        }
> > > > > > >    }
> >
> > > > > > > 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
> >
> > ...
> >
> > 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]<nhusers%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>
>


-- 
thanks

cliff

-- 
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