Nhibernate one to many delete not working
Hi I have a one to many ComplianceSet -> ComplianceItem. ComplianceItem has a one to many ComplianceItem -> ComplianceItemInstance.
I have
ComplianceSet
HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();
And
ComplianceItem
HasMany(x => x.GetUserComplianceItemInstances()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();
Then in my code I have
userComplianceSet.GetUserComplianceItems().FirstOrDefault(....);
...
userComplianceItem.RemoveUserComplianceItemInstance(userComplianceItemInstance);
this code returns
deleted object would be re-saved by cascade (remove deleted object from associations)[DecisionCritical.Core.Domain.UserComplianceSet#12]
Now this is very frustrating. If I remove the cascade from both collections the code returns success but the db show's that it didn't do anything. the ComplianceItemInstance.ComplianceItemId field is still populated and of course the item is still there. In anycase, I just want to be able to delete a child from a collection, call save on the object holding the collection and have the freakin thing go away. I've tried all manner of permutations of cascade, save ( saving the s开发者_运维技巧et, saving the item ) adding delete to the ComplianceItemInstance and so and can't get this to work.
Please help
I have been struggling with the same thing. Reaction is a bit late, but maybe future readers can benefit.
The solution of allowing null as foreign key on the child table works, but it might not be desirable from a database design point of view if your child cannot exist without a parent anyway. Modifying the database design purely because NHibernate requires it, is not something I prefer. Also changing from bidirectional to unidirectional was undesirable for me. So I dove in and tried all sorts of combinations of mappings.
What I found out is that using inverse = true fixed the problem. First I thought this was bad behavior from NHibernate, since inverse = true is mostly explained as making the child collection responsible for the relation, which I thought I already covered by manually updating both child and parent. But this responsibility is more of a database thing than anything else.
Using inverse = true, it is still possible to delete a child by removing it from the parent, as long as you have Cascade.AllDeleteOrphan on the parent-side of the mapping, everything will be correctly updated. If you choose to use Cascade.All, you must also explicitly delete the child.
If the parent is not loaded you can also choose to delete the child immediately, simply by deleting it in the current session. But this does not work if the parent is loaded in which case it will give the cascade re-save issues.
Bottom line for me is, inverse works. And I have not found a scenario in which inverse = false gives me better results, but I might get back to that opinion once diving deeper into NHibernate.
精彩评论