Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In NHibernate, my check if entity is dirty fails

Tags:

nhibernate

Background

Similar to this question, I need to determine if an entity in my NHibernate application is dirty or not. There is a "IsDirty" method on ISession, but I want to check a specific entity, not the whole session.

This post on nhibernate.info describes a method of checking an entity by fetching its database state and comparing it to the current state of the entity.

Problem

I've copied that method, but it isn't working for me. See the code:

public static Boolean IsDirtyEntity(this ISession session, Object entity)
{
    String className = NHibernateProxyHelper.GuessClass(entity).FullName;
    ISessionImplementor sessionImpl = session.GetSessionImplementation();
    IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
    IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);
    EntityEntry oldEntry = sessionImpl.PersistenceContext.GetEntry(entity);


    if ((oldEntry == null) && (entity is INHibernateProxy))
    {
        INHibernateProxy proxy = entity as INHibernateProxy;
        Object obj = sessionImpl.PersistenceContext.Unproxy(proxy);
        oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
    }

    Object [] oldState = oldEntry.LoadedState;
    Object [] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
    Int32 [] dirtyProps = persister.FindDirty(currentState, oldState, entity, sessionImpl);

    return (dirtyProps != null);
}

The line that that populates the currentState array by calling persister.GetPropertyValues() is the problem. The array is full of nulls, instead of the actual values from my entity.

When I stepped into the code, I found that reflection is being used to get the values from the fields -- but the fields are null. This seems like a result of the proxy, but I'm not quite sure where to go from here.

like image 324
quip Avatar asked Nov 06 '09 21:11

quip


1 Answers

I changed my default-access strategy from "field.camelcase-underscore" to "property" and now the persister.GetPropertyValues() method returns correct values.

Too early to declare victory, but seems interesting. I was using the field access strategy because I had code in my entities' properties to track dirty state. Since I'm removing that code and going to rely on NH to determine dirty state, I was able to use the property access strategy.

like image 156
quip Avatar answered Oct 17 '22 09:10

quip