tags:

views:

2061

answers:

3

I have a NewsFeed object mapped as such:

<class name="NewsFeed">
    <id name="NewsFeedId">
        <generator class="guid"/>
    </id>

    <property name="FeedName" not-null="true" />
    <property name="FeedURL" not-null="true" />
    <property name="FeedIsPublished" not-null="true" />
</class>

And Users who can have a Set of Selected feeds that they might be intereseted in, mapped like so:

<class name="SystemUser">
    <id name="SystemUserId">
        <generator class="guid"/>
    </id>


    <set name="SelectedNewsFeeds" table="SystemUserSelectedNewsFeeds" cascade="all">
        <key column="SystemUserId" />
        <many-to-many column="NewsFeedId" class="NewsFeeds.NewsFeed, Domain"/>
    </set>

</class>

What I want to happen is when I delete the parent NewsFeed then all of the SelectedNewsFeed references get deleted too, without having to load each SystemUser and delete the NewsFeed by hand.

What is the best way to achieve this?

UPDATE: Using cascade="all-delete-orphan" instead of "all" still results in an exception when deleting the NewsFeed:

The DELETE statement conflicted with the REFERENCE constraint "FKC8B9DF81601F04F4". The conflict occurred in database "System", table "dbo.SystemUserSelectedNewsFeeds", column 'NewsFeedId'.
A: 

change

cascade="all"

to

cascade="all-delete-orphan"

Reference

Matt Briggs
Hmm.. I'm using NHibernate 2.2 and this happens: [MappingException: Unsupported cascade style: delete-orphans]
jmcd
Ah.. should be cascade="all-delete-orphan"
jmcd
Unfortunaltely no dice: The DELETE statement conflicted with the REFERENCE constraint "FKC8B9DF81601F04F4". The conflict occurred in database "System", table "dbo.SystemUserSelectedNewsFeeds", column 'NewsFeedId'.
jmcd
+1  A: 

Since the relation inside the set is many-to-many, nHibernate is not able to tell which end of the relationship is the child and which is the parent, and the quickest way for me to achieve what I wanted was just to write some SQL that I sent through my repository that deleted the respective news feeds from the collection, and then deleted the parent news feed. The next time the collection was hydrated the changes were reflected.

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

jmcd
+2  A: 

JMCD

Your second approach:

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

is actually what the nHibernate folks recommend in their documentation.

Don't use exotic association mappings.

Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

Using two one-to-many associations adds the flexibility to easily add other attributes to the "subscription", such as notification preferences for that particular subscription.

Trent