I have the following hierarchy of entities:

Parent
Child
Grandchild

The Parent entity contains a property for the Child entity.  The Child
entity contains a property for the Grandchild entity.  Each
relationship is a one-to-one relationship that is mapped in
the .hbm.xml file using one-to-many in order to use the cascade
option, all-delete-orphan (see NH-1262 http://216.121.112.228/browse/NH-1262).

I am using both a MergeEventListener and a SaveOrUpdateEventListener
to get notified when the Grandchild entity is saved so I can perform
logic in case the Grandchild is saved due to a cascade from Parent or
Child.  I check the Version property of the Grandchild entity to
perform certain logic based on whether or not the entity is transient
or persisted.

In the following scenario, the SaveOrUpdate (or Merge) events are not
being fired for the Grandchild entity until after the entity has been
"persisted" or had its Version number changed from 0 to 1:

- Select an existing Parent from the database that contains a Child
and Grandchild.
- Create a new/transient Grandchild object and add it to the
Parent.Child.Grandchild property.
- Merge (or SaveOrUpdate) the Parent entity.

    using (ISession session = this.OpenSession())
    {
        using (ITransaction transaction = session.BeginTransaction())
        {
            Parent startingParent =
session.Get<Parent>(this.ExpectedParentId);

            Grandchild closedGrandchild = new Grandchild {StatusValue
= "Closed"};
            startingParent.Child.Grandchild = closedGrandchild;

            Parent actualParent =
(Parent)session.Merge(startingParent);

            transaction.Commit();
        }
    }

When session.Merge or session.SaveOrUpdate are called, the
MergeEventListener (or SaveOrUpdateEventListener) for the Parent
entity gets fired, but no other events are fired at this time.
However, when the SaveOrUpdateEventListener is finally fired for the
Child and Grandchild entities during transaction.Commit(), the
Grandchild.Version property is already set to 1 (i.e., persisted).
The Version was updated during the Merge of the Parent entity when the
merge/save was cascaded down to the Grandchild entity:

[Class=NHibernate.Engine.CascadingAction]:  cascading to merge:
NHibernate.Test.NHSpecificTest.NHEvents470.Grandchild
[Class=NHibernate.Engine.VersionValue]:  unsaved-value: 0
[Class=NHibernate.Event.Default.AbstractSaveEventListener]:  transient
instance of: NHibernate.Test.NHSpecificTest.NHEvents470.Grandchild
[Class=NHibernate.Event.Default.DefaultMergeEventListener]:  merging
transient instance
[Class=NHibernate.Event.Default.AbstractSaveEventListener]:  generated
identifier: beb25e35-45cd-4093-b88e-9b166c5ca7f0, using strategy:
NHibernate.Id.Assigned
[Class=NHibernate.Event.Default.AbstractSaveEventListener]:  saving
[NHibernate.Test.NHSpecificTest.NHEvents470.Grandchild#beb25e35-45cd-4093-
b88e-9b166c5ca7f0]
[Class=NHibernate.Engine.VersionValue]:  unsaved-value: 0
[Class=NHibernate.Engine.Versioning]:  Seeding: 1

The behavior is similar for SaveOrUpdate as the Grandchild.Version
property gets incremented to 1 before the SaveOrUpdateEventListener is
called.

Is this the expected behavior of NHibernate?  I would've expected the
MergeEventListener or SaveOrUpdateEventListener to get called when
each "child" entity is being saved on the cascades at the same time as
the "parent" object is being saved instead of seeing the events fired
for the "child" entities during transaction.Commit().

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