views:

155

answers:

3

In my current project, we got a rather unusual request(to me). The client wants all the deletion procedure to mark a flag instead of physically delete the record from the database table. It looks pretty easy at the first glance. I just have change

public void DeleteRecord(Record record)
{ 
    record.DeleteAndFlush();
}

public IList GetAllRecords()
{
    Record.FindAll().ToList();
}

To

public void DeleteRecord(Record record)
{ 
   record.Deleted = true;
   record.UpdateAndFlush();
}

public IList GetAllRecords()
{
    Record.FindAll().Where(x=>x.Deleted==false).ToList();
}

But as after I get a bit of time and think though again. I found that this little change would cause a huge problem in my cascade settings. As I am pretty new to the Active Record business. I wouldn't trust myself to simply change all the CascaeEnum.Delete to CascadeEnum.SaveUpdate. So, I am looking some input here.

1) Is the mark a flag instead of physical requirement a common one?

2) If the answer to question 1 is Yes, then I believe there is something built-in in NHibernate to handle this. Can someone tell me what is the right approach for this kind of problem?

Thanks for your input.

+1  A: 

This is known as Soft Deletes and it is very common. There is some debate about the best practice - check out this recent blog post: http://ayende.com/Blog/archive/2009/08/30/avoid-soft-deletes.aspx

cbp
Thanks for the quick reply. it feels good to find that even big names such as ayende has similar concern as mine :)
Wei Ma
+2  A: 

This is quite common and called "soft delete". Here's an implementation of this for NHibernate.

Mauricio Scheffer
Thanks Mauricio, I tried to mark your reply as answer but the system only allows one answer. So I have to go chronically and cbp's reply is about 1 minute early. Thanks for the answer.
Wei Ma
So here's an upvote to at least give you some of the *rep* of an accept, if not the tick itself :-)
paxdiablo
That's what I did :)
Wei Ma
+1  A: 

This is a relatively common request and it's sometimes implemented for (at least) two reasons:

  1. Auditing and history - Marking a row as deleted rather than physically deleting it means the information is still available if needed (including recovery of information if, for example, you accidentally delete the wrong customer).
  2. Performance - I've seen systems that batch up deletes with this method so they can be performed physically at a quiet time. I'm doubtful this is needed with modern DBMS' but I can see how it might have been so in the past if you wanted to avoid cascaded deletes on severely overloaded systems (of course, you shouldn't be running on such a system in the first place). Oracle 8 introduced a feature like this where you could drop columns in this manner and it would only physically remove them when you asked - you couldn't use the column at all even though the information had not yet been removed fully. Granted removal of a column is more intensive than removal of a row but it may still help.
paxdiablo