NHibernate Gotchas - Many-to-many duplicate records

This isn't exactly a "gotcha" since it just has to do with writing mappings correctly and thoughfully. But if you are like me, you use CodeSnippets in VisualStudio 2005 to create all your mappings...the carpal tunnel looming upon me after hand coding a million mapping files (zzzz) forced me into working smarter with Snippets. Anyways, here was my situation. Minor, but took about 15 minutes to debug. Say two classes, class A and Class B, require a many-to-many relationship with each other. Within Nhibernate, one of the classes needs to be in charge of maintaining the relationship. What this means is just that a decision needs to be made on which class Adds/Removes instances from the collection to persist the relationship correctly. On my project, I am using NHibernate.Generics. I decide that Class A should maintain the relationship so in my Class A constructor I have:
_classBs = new EntityList( delegate(ClassB r) { r.ClassAs.Add(this); }, delegate(ClassB r) { r.ClassAs.Add(this); },InitializeOnLazy.Always,OnDuplicate.DoNotAdd);

Now, in my ClassB constructor I have this:
_classAs= new EntityList( delegate(ClassA t) { t.ClassBs.Add(this); }, delegate(ClassA t) { t.ClassBs.Add(this); });
Then, in my Class A mapping I have this:
<bag name="ClassBs" access="NHibernate.Generics.GenericAccessor, NHibernate.Generics" lazy="false" cascade="all" table="ClassB_ClassA" inverse="true">
Then in my Class B mapping I have:

In my case, I had forgotten to put the "inverse=true" attribute for the collection of ClassBs in ClassA. This is because I use snippets and more often I am doing one-to-many collections where the "one" maintains the relationship and so I wouldn't have "inverse-true" expressed on the many-side. This was resulting in duplicate records in my join-table (ClassB_ClassA) because NHibernate wasn't sure WHO was maintaining the relationship...that's what the little "inverse" flag helps establish.

This article is part of the GWB Archives. Original Author: Mike Nichols

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.