TroyB
TroyB

Reputation: 195

fluent nhibernate Cascade creates new records instead of updating them

So being new to n-hibernate and fluent n-hibernate for that matter, I'm having some confusion with mapping and cascading changes to child objects.

I have a object that has several collections, when I create a new object it creates the child objects and inserts them into their respective tables. That's all fine and good. However, when I go to update the parent with changes in the child objects on the surface it appears to flow just they way I want it to. The kicker is that when looking into the db I see that instead of updating the child object record it has inserted new records and removed the association to the parent object from the original records instead of just updating them.

To add additional explanation we are using AutoMapping and MappingOverrides. So here is a brief look at the code I'm working with.

public class ParentObjectOverride : IAutoMappingOverride<ParentObject>
{
    public void Override(AutoMapping<ParentObject> mapping)
    {

        mapping.HasMany(x => x.Chid1).Cascade.SaveUpdate().Table("chid1Table");
        mapping.HasMany(x => x.Child2).Cascade.SaveUpdate().Table("child2Table");

    }
}
public class Child1Override : IAutoMappingOverride<Child1>
{
    public void Override(AutoMapping<Child1> mapping)
    {
        mapping.References(x => x.ParentObject).Cascade.All();
    }
}

public class Child2Override : IAutoMappingOverride<Child2>
{
    public void Override(AutoMapping<Child2> mapping)
    {
        mapping.References(x => x.ParentObject).Cascade.All();
    }
}

There really isn't a case where the child objects are saved independantly of the ParentObject. I've tried cascade.all() as well as cascade.saveupdate() both produce the same results.

I've read several posts about using AllDeleteOrphan, but I don't see why it shouldn't just update the child rows instead of making new rows and deleting the old ones. Maybe I just don't understand the mapping concept.

Any assistance is appreciated

Upvotes: 2

Views: 1617

Answers (1)

Modus Operandi
Modus Operandi

Reputation: 641

Without seeing the relevant code I will have to guess, but here's how it works.

// Case 1
var parent = LoadParentAndChildrenFromDatabase();
parent.Child1 = new Child1();
parent.Child2 = GetChild2OjbectFromSomewhere();
SaveParentAndChildrenToDatabase();

// Case 2
var parent = LoadParentAndChildrenFromDatabase();
parent.Child1.SomeProperty = "new_value";
parent.Child2.AnotherProperty = 15;
SaveParentAndChildrenToDatabase();

In Case 1 you will always insert new rows because your Parent object is actually throwing out the old Child objects and replacing them with completely different ones. That's why you need to use DeleteOrphan option — so that the old, no longer used Child rows get removed from the database when the new ones are inserted.

Case 2, however, should update existing rows, since the object stays the same and only its properties are updated.

I hope this answers your question.

Upvotes: 2

Related Questions