I’m currently using NHibernate as my data access layer, using Fluent NHibernate to create the mapping files for me. I have two classes, TripItem and TripItemAttributeValue, which have a many-to-many relation between them.
The mapping is as follows:
public class TripItemMap : ClassMap<TripItem2> { public TripItemMap() { WithTable('TripItemsInt'); NotLazyLoaded(); Id(x => x.ID).GeneratedBy.Identity().WithUnsavedValue(0); Map(x => x.CreateDate, 'CreatedOn').CanNotBeNull(); Map(x => x.ModifyDate, 'LastModified').CanNotBeNull(); /* snip */ HasManyToMany<TripItemAttributeValue>(x => x.Attributes).AsBag() .WithTableName('TripItems_TripItemAttributeValues_Link') .WithParentKeyColumn('TripItemId') .WithChildKeyColumn('TripItemAttributeValueId') .LazyLoad(); } } public class TripItemAttributeValueMap : ClassMap<TripItemAttributeValue> { public TripItemAttributeValueMap() { WithTable('TripItemAttributeValues'); Id(x => x.Id).GeneratedBy.Identity(); Map(x => x.Name).CanNotBeNull(); HasManyToMany<TripItem2>(x => x.TripItems).AsBag() .WithTableName('TripItems_TripItemAttributeValues_Link') .WithParentKeyColumn('TripItemAttributeValueId') .WithChildKeyColumn('TripItemId') .LazyLoad(); } }
At some point in my application I fetch existing attributes from the database, add them to tripItem.Attributes, then save the tripItem object. In the end, the TripItems_TripItemAttributeValues_Link never gets any new records, resulting in the relations not being persisted.
If it helps, these are the mapping files generated by Fluent NHibernate for these classes:
<?xml version='1.0' encoding='utf-8'?> <hibernate-mapping xmlns='urn:nhibernate-mapping-2.2' default-lazy='true' assembly='ETP.Core' namespace='ETP.Core.Domain'> <class name='TripItem2' table='TripItemsInt' xmlns='urn:nhibernate-mapping-2.2' lazy='false'> <id name='ID' column='ID' type='Int32' unsaved-value='0'> <generator class='identity' /> </id> <property name='CreateDate' column='CreatedOn' type='DateTime' not-null='true'> <column name='CreatedOn' /> </property> <property name='ModifyDate' column='LastModified' type='DateTime' not-null='true'> <column name='LastModified' /> </property> <bag name='Attributes' lazy='true' table='TripItems_TripItemAttributeValues_Link'> <key column='TripItemId' /> <many-to-many column='TripItemAttributeValueId' class='ETP.Core.Domain.TripItemAttributeValue, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' /> </bag> </class> </hibernate-mapping>
and
<?xml version='1.0' encoding='utf-8'?> <hibernate-mapping xmlns='urn:nhibernate-mapping-2.2' default-lazy='true' assembly='ETP.Core' namespace='ETP.Core.Domain'> <class name='TripItemAttributeValue' table='TripItemAttributeValues' xmlns='urn:nhibernate-mapping-2.2'> <id name='Id' column='Id' type='Int32'> <generator class='identity' /> </id> <property name='Name' column='Name' length='100' type='String' not-null='true'> <column name='Name' /> </property> <bag name='TripItems' lazy='true' table='TripItems_TripItemAttributeValues_Link'> <key column='TripItemAttributeValueId' /> <many-to-many column='TripItemId' class='ETP.Core.Domain.TripItem2, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' /> </bag> </class> </hibernate-mapping>
What am I doing wrong here ?
@efdee
I was having the same problem and spent almost two days on this. I had a many to many relationship and the link table wasn’t being updated either. I’m new to NHibernate, just trying to learn it so take everything I say with a grain of salt.
Well it turned out that it’s not Fluent NHibernate, nor the mapping, but me not understanding how NHibernate works with many-to-many. In a many-to-many relationship if collections on both entities aren’t populated, NHibernate doesn’t persist data to the link table.
Let’s say I have this entities in a many-to-many relationship :
when I add to a location to Contact.Locations, I have to make sure that the contact is also present inside location.Contacts.
so to add a location i have this method inside my Contact class.
This seems to have solved my problem, but like I said I’m just picking up NHibernate and learning it, may be there’s a better way. If anyone has a better solution, please post.
This is the post that pointed me to check both collections: http://www.coderanch.com/t/217138/Object-Relational-Mapping/link-table-of-ManyToMany-annotation