Hi Chris

This is great in a situation where you are dealing with the session
the whole time, meaning every business operation has an equivalent
operation being performed using the session.

In our application our user is manipulating a complex domain model
accross various user interfaces.
We load up the model using a session and then close the session.
The user can then manipulate the model, adding elements, moving,
deleting and changing them without persisting them to the Nhibernate
session.
When the user is finished with his work, he elects to save his changes
to the database.
At this point we open the session and pass it our model. use a
session.saveorupdate(model) and then session.flush().
This is where Nhibernate should do its work of figuring out what to
add, update, delete, etc based on the relationships between the domain
model elements.

This is why your solution won't work in our case.

Regards
Dirk

On Sep 11, 12:00 am, Chris Nicola <[email protected]> wrote:
> Ooops, I should have added that (I believe) you will have to have loaded the
> child object in the same session as that commit to have the changes
> persisted.  Otherwise call Session.SaveOrUpdate(split) to add the object to
> your open session so something like this might be more clear:
>
> using (ses = SessionFactory.OpenSession())
> using (tx = ses.BeginTransaction()){
>   var split =  ses.Get<EntrySplit>(id);
>   split.Entry = newParent;
>   tx.Commit();
>
> }
>
> Obviously if you have a lot of items to re-parent you can Query all the
> splits and toss a loop in there.
>
> using (ses = SessionFactory.OpenSession())
> using (tx = ses.BeginTransaction()){
>   var newParent =  ses.Get<Parent>(idNewParent);
>   foreach (child in ses.Get<Parent>(idOldParent).Children)
>     child.Parent = newParent;
>   tx.Commit();
>
> }
>
> In my application the domain logic I have also allows me to write something
> like this:
>
> using (ses = SessionFactory.OpenSession())
> using (tx = ses.BeginTransaction()){
>   var newParent = ses.Get<Parent>(idNewParent);
>   var oldParent  = ses.Get<Parent>(idOldParent);
>   newParent.AddChildrenFromCollection(oldParent.Children)  //This adds each
> child in the collection one at a time, make sure to also change it's parent
> reference first
>   tx.Commit();
>
> }
>
> Hope that helps clarify things,
> Chris
>
> On Thu, Sep 10, 2009 at 1:49 PM, Chris Nicola <[email protected]> wrote:
> > Or to put it another way for you, nHibernate does not "handle" the
> > "re-parenting", it handles persisting the objects in your domain.
>
> > If you want to re-parent, then re-parent:
>
> > If it is one-to-many this should be able to be handled by:
>
> > child.Parent = newParent;
>
> > If it is many-to-many you may need to have a method like:
>
> > ParentA.RemoveChild(child);
> > ParentB.AddChild(child);
>
> > I have a one-to-many relationship which has inverse set on it and I defined
> > the following on the Child (Entry is the parent entity and EntrySplit is the
> > child):
>
> >     public virtual Entry Entry {
> >       get { return _entry; }
> >       set {
> >         if (_entry != value) {
> >           if (_entry != null)
> >             _entry.EntrySplits.Remove(this);
> >           _entry = value;
> >           if (_entry != null)
> >             _entry.EntrySplits.Add(this);
> >         }
> >       }
> >     }
>
> > Also I have these methods defined on the Parent in case I want to add or
> > remove on the collection:
>
> >     public virtual EntrySplit AddSplit(EntrySplit split) {
> >       split.Entry = this;
> >       return split;
> >     }
>
> >     public virtual EntrySplit AddNewSplit(decimal amount) {
> >       var split = new EntrySplit {Amount = amount};
> >       AddSplit(split);
> >       return split;
> >     }
>
> > So if I want to "re-parent" something like this should work:
>
> > using (tx = Session.BeginTransaction()){
> >   split.Entry = newParent;
> >   tx.Commit();
> > }
>
> > Looks like nHibernate is doing it's job to me.
>
> > Chris
>
> > On Thu, Sep 10, 2009 at 11:23 AM, José F. Romaniello <
> > [email protected]> wrote:
>
> >> You want changes to be reflected in the persistence model, but you don't
> >> take care of what you have currently in memory.
> >> IMHO: this is an object operation, let nhibernate to take care to update
> >> the persistent model, but do the right in the object model.
>
> >> 2009/9/10 Paladin_za <[email protected]>
>
> >>> I think NHibernate is a great ORM, but I can't help but feel that in
> >>> some cases the product forces me to manage persistence issues it could
> >>> have dealt with itself.
>
> >>> My biggest gripe at the moment is the case of re-parenting.
>
> >>> For example, I have a parent object with a collection of child objects
> >>> and I want to move one of the existing child objects to a different
> >>> parent object.
>
> >>> From a SQL perspective this could be done with the simple update
> >>> statement UPDATE ChildTable SET ParentId = DifferentParentId where
> >>> ChildId = TheIDOfTheChildToMove.
>
> >>> But Nhibernate refuses to make this easy. From what I can read on the
> >>> web, there are 2 solutions.
>
> >>> First solution. Change the HasMany mapping on the parent object to use
> >>> CascadeAll. This lets re-parenting work fine, but breaks deletes. How
> >>> do we typically delete an object in our models, we set the
> >>> ChildObject.Parent reference to null and remove the ChildObject from
> >>> the Parent's ChildObjects collection. Now NHibernate de-references the
> >>> objects, but the data still remains in the database. Outcome =
> >>> Developer has to do database programming by calling session.Delete.
>
> >>> Second solution. Change the HasMany mapping on the parent object to
> >>> use CascadeAllDeleteOrphan. Delete works great now. As per the
> >>> documentation. amazing. Except, re-parenting breaks. And we get the
> >>> stupid object would be resaved exception. To "fix" this the developer
> >>> must first "delete" the object from the session and then re-attach it
> >>> to the new parent object.
>
> >>> The above solutions invariably require my domain model to have some
> >>> knowledge of the underlying data access implementation. This flies in
> >>> the face of persistence ignorance which Nhibernate champions in every
> >>> other area.
>
> >>> Can someone please explain why this is even considered acceptable?
>
> >>> I can only hope that someone wiser than me has a solution to this.
--~--~---------~--~----~------------~-------~--~----~
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