Saturday, December 03, 2005

NHibernate Many-To-Many Confusion

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:

Person p1 = TestFactory.CreateDefaultMember();

Person p2 = TestFactory.CreateDefaultMember();

p2.FName = "Bubba";

Person p3 = TestFactory.CreateDefaultMember();

p3.FName = "Goober";

p1.Save();

p2.Save();

p3.Save();

// cruft elided

p1.Delete();

p2.Delete();  //mass ugliness here!!

p3.Delete();

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">

   <key>

      <column name="PersonID" sql-type="int" not-null="true"/>

   </key>

   <many-to-many class="nUGSoft.Entities.PersonType, nUGSoft.Entities">

      <column name="PersonTypeID" sql-type="int" not-null="true"/>

   </many-to-many>

</bag>

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.

2 comments:

Anonymous said...

Thanks for the feedback Jim. I've posted an updated version to address this (see: http://blogs.intesoft.net/simon/archive/2005/12/04/41.aspx)

Many thanks
- Simon

Anonymous said...

This really helps me.

Thanks a lot!



--
Regards,

Maximilian Haru Raditya

Subscribe (RSS)

The Leadership Journey