I’m having trouble understanding how NHibernate knows anything about objects removed from association (and then execute cascading style like delete-orphant). I mean, at a database level if I wanted to remove an association I’d have to physically log on and remove some FK. How does this happen in NH world? Do I remap my classes, remove previously established parent/child association (relationship), NH does comparative analysis, digs that something has been changed and then takes appropriate action? In this post Ayende talks about different cascading styles and delete-orphat is described as “… In addition to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it …” How does this removal happen?
I’m having trouble understanding how NHibernate knows anything about objects removed from association (and
Share
NHibernate watches all the mapped collections mapped that are owned by objects in the NHibernate session. As you make changes (adding/removing) NHibernate marks them as dirty. When it is time to flush the changes it compares the elements in the dirty collections and is able to identify what items have been added and removed. Depending on the cascade options for the collection NHibernate might then persist those changes to the database.
This is why you should always declare collection properties using interfaces (IList, ISet, etc.) and never replace a collection property on an object that has been loaded using NHibernate.
Additional info requested in comments:
There is a useful discussion by Fabio Maulo (NHibernate lead developer) of collection mapping here which I would strongly recommend to read. But to try and provide a brief answer to your questions:
But how does NH know that association between objects has been removed?
Generally when working in the OO model with many associations we manage relationships at the parent. That is, a child is considered to be associated with the parent when it is in a parent’s collection. E.g.
Similarly removing an item from a collection breaks the association (assuming correct mapping attributes have used)
This is the opposite of how things work in the relational world where we manage the relationship at the child via the foreign key on the child row.
For a more detailed understanding there is nothing like downloading the NHibernate source code, creating a simple test case and then stepping through in the debugger.
What’s the reason behind the “This is why…”
There are a number of things NHibernate takes care of in managing in association collections. It does this by using its own collection classes that keep track of whether they are dirty, what state they were in when they were loaded from the db and a number of other cool things. If you replace those objects then NHibernate loses that capability. So, for instance if you want to get rid of all the items in a collection you should do:
You should NEVER do:
For further reading you might also want to take a look at this.