Joel
Joel

Reputation: 7569

NHibernate Interceptor not working

I have set up an IIntercpetor to update the timestamp (last modification date) of entities when they are saved or updated.

My implementaion looks like this:

public class NhInterceptor : EmptyInterceptor
{
    public override bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, NHibernate.Type.IType[] types)
    {
        var baseEntity = entity as EntityBase;
        if (baseEntity == null)
            return false;

        baseEntity.LastModification = DateTime.Now;
        return true;
    }

    public override bool OnFlushDirty(object entity, object id, 
        object[] currentState, object[] previousState, 
        string[] propertyNames, NHibernate.Type.IType[] types)
    {
        var baseEntity = entity as EntityBase;
        if (baseEntity == null)
            return false;

        baseEntity.LastModification = DateTime.Now;
        return true;
    }
}

This code is hit, and debugger shows that baseEntity.LastModification has the right value, just before returning.

However, my Json output (in Web API) shows LastModification as 0001-01-01T00:00:00 and if i check my created entity in database, it shows same result as well.

Why does this not work?

Upvotes: 2

Views: 1738

Answers (2)

Joel
Joel

Reputation: 7569

I decided to give you my working solution, based on Hylaean's answer.

My Interceptor class:

public class NhInterceptor : EmptyInterceptor
{
    public override bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, NHibernate.Type.IType[] types)
    {
        var baseEntity = entity as EntityBase;
        if (baseEntity == null)
            return false;

        var lastModificationPropName = ExpressionUtil
            .GetPropertyName<EntityBase>((e) => e.LastModification);

        for (int i = 0; i < propertyNames.Length; i++)
        {
            if (lastModificationPropName == propertyNames[i])
            {
                state[i] = DateTime.Now;
                return true;
            }
        }

        return true;
    }

    public override bool OnFlushDirty(object entity, object id, 
        object[] currentState, object[] previousState, 
        string[] propertyNames, NHibernate.Type.IType[] types)
    {
        var baseEntity = entity as EntityBase;
        if (baseEntity == null)
            return false;

        var lastModificationPropName = ExpressionUtil
            .GetPropertyName<EntityBase>((e) => e.LastModification);

        for (int i = 0; i < propertyNames.Length; i++)
        {
            if (lastModificationPropName == propertyNames[i])
            {
                currentState[i] = DateTime.Now;
                return true;
            }
        }
        return true;
    }
}

My Expression util class:

public static class ExpressionUtil
{
 public static string GetPropertyName<T>(Expression<Func<T, object>> expression)
    {
        var body = expression.Body as MemberExpression;

        if (body == null)
        {
            body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
        }

        return body.Member.Name;
    }
}

Upvotes: 1

Hylaean
Hylaean

Reputation: 1287

You need to change the currentState values. First lookup in propertyNames for "LastModification", then change currentState of the index if found. You can check in IType[] for the type as well.

Upvotes: 2

Related Questions