More NHibernate learning tonight, this time with many-to-many relationships. We’ve been using Simon Green’s killer NHibernate templates for CodeSmith to generate business entities and mapping files.
I found one hitch, though, via my unit tests: I was losing all entities of a similar type when deleting one of them. ‘Tis a puzzlement. Using the debugger and peering at the database while stepping through, I found deleting the first entity resulted in the remaining entities getting deleted too.
Background: the entities are Person types with names, e-mails, etc., but also hold an IList defining a many-to-many relationship with a PersonType entity which stores, well, the type of person we’re dealing with. (Member, speaker, sponsor, etc.)
My unit test looks like so:
Personp1 = TestFactory.CreateDefaultMember();Person p2 = TestFactory.CreateDefaultMember();
p2.FName ="Bubba";Person p3 = TestFactory.CreateDefaultMember();
// cruft elidedp1.Delete();
p2.Delete(); //mass ugliness here!!
My test died out at the p2.Delete() statement. By using the debugger I noticed that the PersonType record was deleted at the statement p1.Delete(). Hmmm… A quick dig into the mapping file for the Person entity shows the collection defined so:
<bag name="PersonTypes" table="PersonTypeLink" inverse="false" lazy="false" cascade="all">
<column name="PersonID" sql-type="int" not-null="true"/>
<many-to-many class="nUGSoft.Entities.PersonType, nUGSoft.Entities">
<column name="PersonTypeID" sql-type="int" not-null="true"/>
Whoops! Note that portion “cascade=’all’” ? Hibernate’s documentation (forget NHibernate’s dox) says cascading shouldn’t usually be used when dealing with many-to-many or many-to-one relationships. I changed that option to “none” and things look much better now.
I’ll follow up with Simon and see if he’s got some specific reason for having had cascade=”all” set. I’ll post a follow up here if there’s something of interest which comes out of that.