NHiberate is wonderful. Being a newbie, I have at times struggled with some very simple error messages.
I came across this issue while I was trying to delete items from a collection of child objects.
In my mapping, Order has a bag of Orderlines and Orderline has a “navigation property” Order. My application allows amending orderlines or even delete them if they are not processed yet. While deleting I got the deleted object would be re-saved by cascade (remove deleted object from associations) because my cascade was set to “update-save”. Like the error suggested I removed the orderline from order before calling delete.
Well the same error appeared again. Then I tried following
because of my cascading rule I thought that it would be fine to do so as the resulting operation would be to delete the orderline. however, with cascade set to “update-save”, NHibernate tried to set the OrderId null in Orderline table. which would fine (for those who wouldn’t mind orphan orderlines hanging around in the database table). But one of the constraints in the Orderline table is to make sure there is a OrderID (not null and foreign key). well, luckily there was a “cascade” property value to address this type of issue
cascade = “all-delete-orphan”.
To my surprise even changing cascade to “all-delete-orphan” didn’t resolved the original problem. Then, finally I started taking off my steel hat and started stepping through the code (which I should have done earlier) and the problem was at
this command didn’t remove orderline from the collection and hence the association was there at the time of delete request/or saveupdate request.
Then I started looking other areas such as my equality comparer for entity. And that’s it. the problem was there.
Lesson: Make sure your equality comparer is robust enough. I changed mine to the code that was in Nhibernate cookbook 3.0 and that resolved it.
Note: once the equality comparer is fixed, both delete and SaveOrUpdate would result in removal of record from the database what is best way is dependent on your Domain, if Order is the aggregate root, use Removing from order and save order, if Orderline is aggregate root again remove orderline from order and delete the orderline.