Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set "cascade delete" option to "Set Null" in Fluent NHibernate?

I am new to Fluent nHibernate and would like to know, if I have two classes Profile and Email mapped one-to-many as following... I want to define a nHibernate mapping fluently so when Profile is deleted, Email will remain in the DB, with a key set to Null. Or in other words to have "ON DELETE SET NULL"

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK4239B252F6539048] FOREIGN KEY([ProfileId])
REFERENCES [dbo].[Profile] ([Id])
ON UPDATE SET NULL
ON DELETE SET NULL

Any help is greately appreciated!

public sealed class ProfileMapping : ClassMap<Profile>
        {
            public ProfileMapping()
            { 
                // Some other fields here ...
                HasMany(x => x.Emails);
            }
        }

    public class EmailMapping : ClassMap<Email>
    {
        public EmailMapping()
        {
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.Address).Not.Nullable().UniqueKey("UX_EmailAddress").Length(254);
            Map(x => x.Confirmed);
        }
    }
like image 747
Alex Cherkasov Avatar asked Dec 01 '11 17:12

Alex Cherkasov


1 Answers

You won't be able to specify this behavior automatically in Fluent NHibernate AFAIK. Although the ON DELETE/ON UPDATE behavior specification is common to all DBs that NHibernate supports, NH/FNH control cascading with specific levels of cascade behavior:

none - do not do any cascades, let the users handles them by themselves.
save-update - when the object is saved/updated, check the assoications and save/update any object that require it (including save/update the assoications in many-to-many scenario).
delete - when the object is deleted, delete all the objects in the assoication.
delete-orphan - when the object is deleted, delete all the objects in the assoication. In addition to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it.
all - when an object is save/update/delete, check the assoications and save/update/delete all the objects found.
all-delete-orphan - when an object is save/update/delete, check the assoications and save/update/delete all the objects found. In additional to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it.

As you can see, "SET NULL" is not one of the available cascade behaviors.

The best you can do in this case is to not cascade at all, and instead to define the relationship as "Inverse" (E-mails "control" what profile they belong to; Profiles do not "own" their E-mails as such), and to implement logic either in your Repository or attached to the NHibernate Session that will remove all references of the child Emails to their parent Profile, then save all the children as "orphan" records before deleting the Profile.

like image 58
KeithS Avatar answered Sep 21 '22 17:09

KeithS