Reputation: 14747
I'm not so sure if this is really trivial to do and I'm just over-complicating stuff, but I've been thinking about this for the good part of the past hour or so.
So I have entities. Hence, NHibernate. What I want to do is to only "deactivate" entities whenever I want to "delete" them, instead of actually removing them physically from the database. (Just cause we don't want to be really deleting records from our data store).
All my entities inherit from a BaseEntity
class with a BaseEntity.Active
property.
What I've got running right now is something like the following in the entity class' mapping file:
<sql-delete>
UPDATE SomeEntityTable SET Active = 0 WHERE Id = ?
</sql-delete>
This works fine, except that I'll have to inject that, customized with the table name, into every single HBM mapping file for every single entity (we're not implementing the BaseEntity
inheritance in any subclassing strategy).
As you can see, that can be a bit menial. The coding would be tedious, the maintenance horrendous, and declaring the table name twice in the same mapping file just rubs me the wrong way.
What I was playing around earlier was whether or not I could implement an event listener; perhaps OnPreDelete
or something, and update the entity's .Active
property, like so:
class BaseEventListener : IPreDeleteListener
{
public bool OnPreDelete(PreDeleteEvent @event)
{
BaseEntity be = @event.Entity as BaseEntity;
if (be != null)
be.Active = false;
return false;
}
}
That way, the whole "deactivation" thingy is automated for all entities that support deactivation.
The problem is, I'm thinking that NHibernate would still build a proper DELETE SQL query that will burn my entity from the data store anyway instead of updating the thing, so this'll just be wasted automagic effort.
How should I go about this?
Upvotes: 2
Views: 372
Reputation: 52725
Since it's pretty clear that you never actually delete your persistent entities (as is the case with most applications), there's is no need to use the Delete
method just because it's there.
An alternative approach:
Active
propertyDelete
method to your base entity that does just thatYes, there is some work involved, but in the long run it's for the best, as you'll still have a maintainable, non-hacky implementation.
Some of the burden can be reduced if you use a code+convention-based mapping approach, like ConfORM or Fluent.
Upvotes: 2
Reputation: 8381
You can use an event listener. You have to add the listener to the configuration as well.
public class SoftDeleteEventListener : DefaultDeleteEventListener
{
protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
{
var softDeletable = entity as BaseEntity;
if (softDeletable != null)
{
softDeletable.Active = false;
}
else
{
base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities);
}
}
}
Upvotes: 3