So, I have a nice domain model built. Repositories handle the data access and what not. A new requirements has popped up that indicates that reasons need to be logged with deletes. Up until now, deletes have been fairly simple => Entity.Children.Remove(child). No internal change tracking was happening as my ORM tool was handling state management. However, I'm not sure exactyl how to handle this.

1) I could keep a deleted children collection in the parent entity and pull the change tracking out of nHibernate and handle it myself.

2) ??????

+1  A: 

Could you implement the IInterceptor interface and override the onDelete functionality to pull the information you need from the entity and send it to logger before you delete (using NHibernate of course)?


No. The reason actually needs to be stored along with delete instead of simply logged. In addition, how would the interceptor have that information?
Craig Wilson
+1  A: 

If deletes are relatively rare for that particular entity type, I would add a flag to the entity to mark it as logically "deleted" rather than actually deleting the row. The application would then have to handle the hiding of these entities under normal circumstances.

If this would cause an unacceptable number of "stale" rows - I would suggest something similar to Watson's answer. Depending on the exact requirements, you could probably get away with logging the deleted data and an extra "reason" field somewhere directly from the application. Using interceptors is more transparent and more pleasing from an auditing point of view, but a separate deletion log (table, database, file) is probably simpler.

+3  A: 

Ok, this sounds crazy and I'm going to take another shot at this -- even though I might be spanked for bad nHibernate usage. Before you delete, why don't you select the children that are going to be deleted (you already have their ids correct?) and do a transformation into whatever entity your going to be using to log your deletes to a table. Add the reason to the entities and save them -- then proceed with your deletes. Best part, you can use a generic entity i.e. "auditInfo" for the result of the transformation, and you can do it within a transaction so you can rollback everything if something fails! OK, maybe crazy but creative right?

Maybe transformation is overkill for this, just have another generic auditinfo entity that your saving the information in another table.
I think this is brilliant. Thank you...
Craig Wilson