简体   繁体   中英

NHibernate cascading problems

I have this mapping in one class:

<class name="Parent">
<set name="Activity" table="ChangeLogs" order-by="ChangeDate desc" cascade="all-delete-orphan">
  <key column="RequestID" />
  <one-to-many class="ChangeLog" />
</set>

And this in the other:

<class Name="Child">
<many-to-one name="Request" class="Request" column="RequestID" />

In the parent, loaded in the current transaction I add to the collection:

parent.Activity.Add(new Child(){/* properties, etc */});

And then I commit the transaction. Any changes to the parent get saved to the database with an update call, but I can't get those children to insert, regardless of cascade values or inverse=true/false/just-save-already. I've been bashing my head against it for a while, reading examples / documentation / etc, and I can't see why it wouldn't work. Am I missing something simple? I've been killing off the server and re-building after every change to make sure things are updating, but nada.

To make matters worse, occasionally it has worked, with various values for inverse, sometimes by adding the Request=parent to the child, sometimes by saving the child separately before adding... and then it quits working later on. I'm boggling o_O

edit: Things tried explicitly since this was posted, rebuild + server restart between every one, none of which generate an insert call or errors:

<set inverse=true>
parent.Activity.Add(new Child(){Request=parent})
<set inverse=true>
parent.Activity.Add(new Child(){})
<set>
parent.Activity.Add(new Child(){Request=parent})
<set>
parent.Activity.Add(new Child(){})
<set inverse=false>
parent.Activity.Add(new Child(){Request=parent})
<set inverse=false>
parent.Activity.Add(new Child(){})

This did work:

<set>
Child c = new Child() {Request = parent};
parent.Activity.Add(c);
Session.Save(c);

But then what's the point of setting a cascade if it's ignored?

edit: after reading a bit of this: http://nhibernate.info/doc/nh/en/index.html#example-parentchild-bidir I tried:

<class Name="Child">
<many-to-one name="Request" class="Request" column="RequestID" not-null=true />

with all 6 of the main ones above, with no luck.

For me it's always a problem to set it properly at one go. At first everything looks good in your code, but I'm actually wondering on which side you are setting the inverse property?

This code works for me:

<class name="Parent" table="Parent">

<bag name="Languages" inverse="true" cascade="all-delete-orphan" lazy="false" fetch="join">
  <key column="parentId" />
  <one-to-many class="Language" />
</bag>

<class name="Language" table="Language">

<many-to-one column="parentId" name="Parent" class="Parent" not-null="true" />

I hope this helps.

This is the correct mapping:

<class name="Parent">
  ...
  <set cascade="all-delete-orphan" inverse="true" ...>
  ...
  </set>
</class>
<class name="Child">
  ...
  <many-to-one .../>
</class>

And the correct usage (assumes an already existing parent):

using (var tx = session.BeginTransaction())
{
    var parent = GetParent();
    parent.Collection.Add(new Child { Parent = parent });
    tx.Commit();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM