I found out why the SaveOrUpdate event is fired: when an entity is
lazily loaded from a one-to-many association, its lock mode is set to
Read, not None (in memory, at least).
If I disable lazy loading, its lock mode is None, and it no longer
fires the event! Strange... or maybe not! :-)

RP

On May 24, 3:58 pm, Fabio Maulo <[email protected]> wrote:
> Ricardo:
> "always check the state of the entity (using "your" extension-method) before
> change the state of the entity."
>
> or Implement
> MyDirtyCheckEventListener using "your" extension-method and register it
> instead DefaultDirtyCheckEventListener
>
> After do it don't forget yo publish the code with the explication somewhere
> in the NET
>
>
>
>
>
>
>
>
>
> On Tue, May 24, 2011 at 11:48 AM, Ricardo Peres <[email protected]> wrote:
> > Fabio,
>
> > I'm sorry that you think that way, I sincerely do think there is a bug
> > in NHibernate. I am not asking for expert advise, otherwise, I would
> > have gone for the NHUsers mailing list, like I usually do...
> > You always ask people to listen to what you say. I believe you are not
> > listening to what I am saying and you are discarding the chance that
> > there is indeed a bug. Unless you want me to continue, this will be my
> > last attempt in convincing you, I will drop this thread.
> > The course of events is:
>
> > 1) if I load an entity from its id, when I check is dirty, no
> > saveorupdate event is fired (I have a listener other than the
> > default);
> > 2) If I load another entity that has a lazy property to the
> > "problematic" entity, when I check is dirty, it fires the saveorupdate
> > event (which, eventually, will change it, but it was unchanged when
> > the saveorupdate event was raised);
> > 3) the two entities are in memory, both are unchanged, I am using the
> > code you published in your blog for checking it; why is the
> > saveorupdate event fired? It will cause an unchanged entity to become
> > dirty!
> > 4) The Equals/GetHashCode implementation is the same on both tests.
>
> > Guys: can anyone please help me understand this? The issue is
> >http://216.121.112.228/browse/NH-2727.
>
> > Fabio: you have always been a great help, and I sincerely thank you
> > for your time!
>
> > RP
>
> > On May 24, 3:36 pm, Fabio Maulo <[email protected]> wrote:
> > > There was and are some cases where ppl file a bug to have an answer by
> > some
> > > expert.
> > > There cases where the expert may fall into the trap.
> > > Have a look to your equality comparer and always check the state of the
> > > entity (using "your" extension-method) before change the state of the
> > > entity.
>
> > > On Tue, May 24, 2011 at 11:25 AM, Ricardo Peres <[email protected]>
> > wrote:
> > > > Fabio,
>
> > > > Forgive me, but I still don't understand why, in one occasion, it
> > > > fires the event, and not on another, depending on how the entity was
> > > > loaded. I thought all entities were equal, but it seems some are more
> > > > equal than others! ;-)
> > > > Please, if you have some time, do check my code; it is very simple and
> > > > straightforward.
>
> > > > RP
>
> > > > On May 24, 3:20 pm, Fabio Maulo <[email protected]> wrote:
> > > > > NH does not check a state of an loaded entity through
> > > > INotifyPropertyChanged
> > > > > so the only way to know if a loaded entity-state is dirty is asking
> > to
> > > > those
> > > > > events if they have something to do.
> > > > > A similar behavior is done by the flush-mode=auto when you fire a
> > > > query...
> > > > > In practice:
> > > > > if you are using lazy-properties (a simple value with lazy or a
> > relation
> > > > > with no-proxy) we may have an issue related to it... but this is only
> > a
> > > > > guess just because only you and God knows your mappings/classes.
>
> > > > > The fact that session.IsDirty fire the SaveOrUpdate event, where
> > neither
> > > > > inserts nor deletes are presents, is not an issue, instead it is the
> > > > default
> > > > > behavior that you can completely override.
>
> > > > > On Tue, May 24, 2011 at 11:11 AM, Ricardo Peres <[email protected]>
> > > > wrote:
> > > > > > Fabio,
>
> > > > > > Don't get me wrong: I have followed the stack trace, and I know why
> > > > > > this is happening (in the code); I just don't understand it.
> > > > > > First of all: from a conceptual point of view, should the
> > > > > > ISession.IsDirty() fire SaveOrUpdate, on non-dirty entities, or on
> > any
> > > > > > entities at all?
> > > > > > Second: why, if we are loading the entity by its it, the event does
> > > > > > not fire, and if we load it from a property of another entity, it
> > > > > > does?
> > > > > > IMHO, if you answer yes to the first question, there is a bug: it
> > > > > > isn't being fired if the entity is not directly loaded.
> > > > > > I don't want to take your time, just to understand this. Am I the
> > only
> > > > > > one who doesn't understand this behavior?
>
> > > > > > Thanks!
>
> > > > > > RP
>
> > > > > > On May 24, 3:05 pm, Fabio Maulo <[email protected]> wrote:
> > > > > > > The only thing done by IsDirty is just fire an event
> > > > > > > DirtyCheckEvent dcEvent = new DirtyCheckEvent(this);
> > > > > > > IDirtyCheckEventListener[] dirtyCheckEventListener =
> > > > > > > listeners.DirtyCheckEventListeners;
> > > > > > > for (int i = 0; i < dirtyCheckEventListener.Length; i++)
> > > > > > > {
> > > > > > > dirtyCheckEventListener[i].OnDirtyCheck(dcEvent);}
>
> > > > > > > return dcEvent.Dirty;
> > > > > > > You can disable/replace/override that event.
>
> > > > > > > On Tue, May 24, 2011 at 10:21 AM, Ricardo Peres <
> > [email protected]>
> > > > > > wrote:
> > > > > > > > Fabio,
> > > > > > > > You have closed JIRA issues NH-2727 saying that it is not an
> > issue.
> > > > > > > > Perhaps you can explain me, because this is bugging me, why
> > does
> > > > the
> > > > > > > > following line raise the SaveOrUpdate event and the next
> > doesn't:
>
> > > > > > > > //raises SaveOrUpdate
> > > > > > > > User u = session.Query<User>().FirstOrDefault();
> > > > > > > > UserGroup ug = u.UserGroup.First();
>
> > > > > > > > //does not raise
> > > > > > > > UserGroup ug = session.Query<UserGroup>().FirstOrDefault();
> > > > > > > > User u = ug.User;
>
> > > > > > > > By the way, in general, why does ISession.IsDirty() fire any
> > > > events?
> > > > > > > > Shouldn't it just check the current state of entities in
> > memory?
>
> > > > > > > > Thank you for your time, once again!
>
> > > > > > > > RP
>
> > > > > > > --
> > > > > > > Fabio Maulo
>
> > > > > --
> > > > > Fabio Maulo
>
> > > --
> > > Fabio Maulo
>
> --
> Fabio Maulo

Reply via email to