I have two entities like so (distilled to only what's relevant):
public class Person {
public virtual Address Address
}
public class Address {
}
Person has a many-to-one relationship with Address, or in object terms, a Person references an Address, and this link is uni-directional (Address does not have a reference back to Person).
Now, if I use this code:
// save a new person with a new address
var person = new Person();
person.Address = new Address();
person.Save();
// change the person's address and save it again
person.Address = new Address();
person.Save();
The first part does what it's supposed to, it creates a new Person and a new Address in the database.
However, the second part will update the existing Person and create a new Address, but it doesn't delete the now-orphaned first address. What do I have to do in order to get NHibernate to recognize that I'm changing the reference to a new entity and automatically 'garbage collect' the orphaned entity? Or do I have to do this manually?
Possible Solution
Although I don't have conclusive evidence that this indeed what's going on, I think the reason for this problem is because of the object-relational impedance mismatch. In programming, we know that objects hold references to other objects, and once those references are lost, garbage collection will come and delete those 'orphaned' objects that no longer have any references pointing to them. In the example I provided, Person has a reference to Address, and once the reference to Address is lost, it will get garbage collected, assuming no other Persons have a reference to it as well.
On the database side, there is no concept of garbage collection. To the database, there is only one-to-many or many-to-many relationships, or in other words, a parent with a collection of children. Going back to Person and Address, we see that this is a one-to-many relationship from Address to Person (each person can only have one address, but an address can belong to many people, such as a household of people that share a common address). The database considers the Address the parent and the Person as a collection of children. Thus, it makes sense that by deleting a Person, the Address should not be deleted as well (put another way, if you have a bookshelf with a collection of books, deleting a book should not delete the bookshelf).
So how do we fix this? We'll have to delete any parents where their child collections are empty. In this case, an Address with an empty collection of Persons should be deleted. This is a business rule, as nothing states that an Address cannot exist by itself, but in the application I'm developing, an Address by itself means nothing if it's not attached to a person, and thus should be eliminated. However, it's entirely possible for the address to remain in an orphaned state until some other Person comes along and references it.