views:

158

answers:

2

Hi

I have two entities: Group and ContactInfo. These are connected with a many-to-many relationship (mapped using Fluent NHibernate).

I'm not able to remove a "ContactInfo" from a Group. The join-table is not updated. (It is when inserting new elements)

My code (excerpt):

public class GroupMap : ClassMap<Group>
{
    public GroupMap()
    {
        Id(x => x.GroupID);
        Map(x => x.GroupName).Not.Nullable();
        References(x => x.Function);

        HasManyToMany(x => x.Contacts)                
            .Inverse()                
            .Cascade.All() // tried Cascade.AllDeleteOrphans()
            .Not.LazyLoad()
            .WithTableName("Contacts");
    }
}

public class ConcactInfoMap : ClassMap<ContactInfo>
{
    public ConcactInfoMap()
    {
        Id(x => x.ContactInfoID);
        References(x => x.ContactInfoType).Not.Nullable().Not.LazyLoad();
        Map(x => x.ContactInfoValue).Not.Nullable();
        References(x => x.Person)
            .Not.LazyLoad();

        HasManyToMany(x => x.Groups)
            .Cascade.All() // tried Cascade.AllDeleteOrphans()
            .Not.LazyLoad()
            .WithTableName("Contacts");                
    }
}

// The helper method
public virtual void RemoveFromGroup(Group group)
{
    this.Groups.Remove(group);
    group.Contacts.Remove(this);
}

// The deletion
contactInfo.RemoveFromGroup(group);
m_ContactInfoRepository.Update(ci);

Any suggestions to what I'm doing wrong? Also, If anyone have any good resources on how to avoid lots of .Not.LazyLoad() , I would highly appreciate it :-)

Updates:

I also noticed that the two ID columns in the join-table is not set to be a primary key. I noticed this when I managed to insert equal rows into it. How do I avoid this? Is this a case where I should use Set over Bag?

I've read up a little on Bag vs Set, and to me it seems like Set perhaps would solve my "unique row" issue, but still, as this is just a join table, my biggest concern is to be able to delete "connection", and remove a ContactInfo from a Group.

I tried removing the Cascade statements as mentioned in the comments, but it didn't make any difference when it came to deleting.

Updates NEW

After doing some debugging I noticed that when I call this.Groups.Remove(group) nothing happens. What can the reason be? Or..I checked the hashcodes in the "Immediate window", and they are not equal. Have I done something wrong or do I just need to override equals()?

Solution

Overriding the Equals for Group and ContactInfo solved it! Are there any rules saying that I should always override it for NHibernate entities?

+1  A: 

I have not done many-to-many, but I would try and change the cascade from

Cascade.All()

to

Cascade.AllDeleteOrphan()

Good link about Cascades: Ayende on Cascades

For a one-to-many if you remove an object from the collection NHibernate will call a delete on the child. For a many-to-many I would think it would call a delete on the join table, but am not 100% sure.

eyston
Thanks, eyston! I've now read the article and tried switching to Cascade.AllDeleteOrphan(). It didn't work though, the join table remained untouchhed
l3dx
Sorry, I wasn't sure if it would. Hope you find an answer.
eyston
A: 

Just to be able to mark this as solved. See question for more details..

Overriding the Equals for Group and ContactInfo solved it! Are there any rules saying that I should always override it for NHibernate entities?

l3dx