Here is the use case: I have an entity that can get saved by being part of an object graph. When this entity is saved, I need to perform some logic based on whether or not the entity is new (being saved for the first time).
Using the example from the first post with the entities, Parent, Child, and Grandchild, I would perform the following: - Select an existing Parent from the database that contains an existing Child and Grandchild. - Create a new Grandchild object and add it to the Parent.Child.Grandchild property. - Save the Parent entity. Because I am saving the Parent entity, I really have no way of knowing if or when the new Grandchild entity will be saved/persisted. That is why we are subscribing to the NHibernate events - so we can be notified of when an entity is saved/persisted and perform appropriate validation or logic before the save occurs. On Apr 22, 2:49 pm, Fabio Maulo <[email protected]> wrote: > perhaps you are looking to wrong events. > Which are exactly your needs ? (try to explain it from the usage point of > view and not what you think is the right behavior of NH). > > > > On Fri, Apr 22, 2011 at 3:20 PM, j gwood <[email protected]> wrote: > > I ran some additional tests: > > > 1) If I create and associate new Parent, Child, and Grandchild objects > > and call ISession.Persist(Parent), the PersistEventListener only gets > > fired for the Parent entity. The SaveOrUpdate events get fired for > > the Child and Grandchild entities. The PreInsert event gets fired for > > all three entities (Parent, Child, and Grandchild). > > > 2) Using the "Merge" test in the original post (i.e., selecting an > > existing Parent entity that contains existing Child and Grandchild > > entities; then adding a new/transient Grandchild entity), I called > > ISession.Persist instead of ISession.Merge. The PersistEventListener > > only gets fired for the Parent entity. The SaveOrUpdate event gets > > fired for the Child and Grandchild entities. The PreInsert event gets > > fired for the Grandchild entity. The PreUpdate event gets fired for > > the Child entity. > > > On Apr 22, 11:57 am, j gwood <[email protected]> wrote: > > > Our Repository exposes a Save(entity) method, which calls either > > > SaveOrUpdate (for transient entities) or Merge (for persisted > > > entities). We call Merge to handle detached entities. > > > > The Persist event listeners only get called from the > > > SessionImpl.Persist or SessionImpl.PersistOnFlush methods. Should we > > > substitute our SaveOrUpdate or Merge calls with Persist? > > > > Or, is there any documentation on when and how often the different > > > Event Listeners get called? > > > > Thanks so much for your help, > > > > Jean > > > > On Apr 22, 7:39 am, Fabio Maulo <[email protected]> wrote: > > > > > The Save/SaveOrUpdate is not so deterministic as you need. Probably > > > > you are looking for Persist. > > > > > -- > > > > Fabio Maulo > > > > > El 21/04/2011, a las 13:50, j gwood <[email protected]> > > escribió: > > > > > > 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 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]. > > 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]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
