tags:

views:

510

answers:

4

I am using NHibernate and have a requirement where in when i am deleting a row i should not hard delete the row instead update the status to delted and set few system properties like who deleted etc.

For doing this i have decided to go with custom sql statement like.

<sql-delete>
  update PPDE set SysStatusID = 2 where PPDID =? 
</sql-delete>

in the sql statement i am able to get reference to just id , but how can i update the SysUserID to the user who delted this row.

Basically how to set up dynamic paramater values in custom sql statements.

Any help is greatly appreciated.

A: 

Can you do this using an interceptor

    public void OnDelete(object entity,
                         object id,
                         object[] state,
                         string[] propertyNames,
                         IType[] types)
    {
        // if entity is myentity 
        // update user property
    }
Surya
I can do this in interceptor but my requirement is not to physically delete a record, instead just update the status to Deleted and Set the UserId to who deleted it.
Yeah, Keep the custom sql in place , as you mentioned in your question. But update the userid in the interceptor, this method should be called before your custom sql.
Surya
A: 

Hibernate will try to automatically replace "?"s with values from your entity. When you call session.Delete(entity) it will use the value of the property that is mapped to the PPDID column.

That being said, I think it is a bad idea to use a custom sql statement in this case. IMHO your code will be difficult to understand and maintain. When a someone sees session.Delete(entity) he would expect a DELETE statement to be performed but instead it will get an UPDATE statement. I would stick to a session.Update(entity) having set the correct values before.

Darin Dimitrov
Thank you very much for the reply. Even though it is bad idea i did not find any alternative to implement soft deletes.I don't want to use session.Update as i have business rules defined in OnDelete method in the interceptor.If i use session.update we won't get to the method OnDelete in the Interceptor where business rules are defined.
+1  A: 

One way to do what you want, is to implement a DeleteEvent-listener, which is triggered when nhibernate decides to delete of entities. From there, based on some logic (typically you look for an interface on the entity), you can decide if you want to hard-delete or soft-delete the entity. And in case you are soft-deleting it, you can update properties such as "IsDeleted", "DeletedAt", "DeletedBy", etc..

A good blog-post describing the above in details can be found at: The NHibernate FAQ - Soft Deletes

Tom Jelen
Even better :).
Surya
i tried implemeting using DeleteEventListener but i encounted a problem with that too. If i delete a entry from a bag and call save on the Parent entity , the deleted entry from the bag is physically getting deleted otherwise it works fine.
Hrm, I don't have visual studio on this computer to play around with it. But could it be because you are missing the ISoftDeletable interface on the entity in your bag?
Tom Jelen
A: 

But there is not a good aproach to have business rules inside a persistance operation. Your business must be independient from the persistance operations like delete.

andres