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