We have an object in our model, call it class X. There are several other classes in our model that have an instance of class X as a property, call them A, B, C, etc. This is essentially a one-to-one mapping, since each X can only belong to one parent class. To map this relationship on the database side, we are currently using a foreign key to the X table in tables A, B, and C. For the NHibernate mappings, we are currently using, in the mappings for the A, B, and C classes:
ManyToOne(a => a.X, m => m.Cascade(Cascade.All));
This mostly works for saving, retrieving, and updating our class Xs - we've had a lot of problems getting NHibernate OneToOne
mappings to work right. The problem is that, when you take your persistent class A and replace its X with a new instance of X and then save that A instance, then the new X instance gets written to the database and the foreign key in the A column gets updated, but the old X does not get deleted, so we now have an orphan X.
We would like those orphaned Xes to be automatically deleted. We would like NHibernate to do it, because X is a complex class with many relationships of its own to other tables that we have cascades set up to handle properly - I have a SQL script set up to delete orphan Xes properly, and it's about 50 lines long.
We are trying to avoid solutions that involve putting a reference in class X to its parent item, since there are a total of 5 classes that it can belong to, and situations such as class A has one X, class B has 2 Xes in named properties, etc.
Things I've tried so far:
Adding DeleteOrphans
to the ManyToOne
mapping - doesn't work
OneToOne
mapping - really wants the key to be in the other table, and doesn't seem to support cascade deletes anyways.
Also considered:
NHibernate doesn't seem to have any support for setting up some kind of even to trigger when things like updates or deletes happen
Apparantly, only the OneToMany
and ManyToMany
mappings support DeleteOrphans
, so, I could make the actual property use some kind of list or set, and use getters and setters to make it look like a normal property to the rest of the model. Sounds very hacky, and it might require having a reference in X to the other classes.
Database trigger - I haven't really checked if SQL Server triggers can be used in this way yet, but it sounds like a very awkward solution.
Does anybody have any ideas for how to make this work?