NHibernate Forge
The official new home for the NHibernate for .NET community

Finding Dirty Properties in NHibernate

Wiki Page Hierarchy

Pages

Page Details

First published by:
Ricardo Peres
on 10-09-2009
Last revision by:
Ricardo Peres
on 06-20-2011
1 person found this article useful.
Article
Comments (8)
History (7)
100% of people found this useful

Finding Dirty Properties in NHibernate

UPDATE: now deals properly with proxies.

The following extension methods to ISession allow finding if a property or entity has changed, and the original value of a property.

 

public static class SessionExtensions

{

    public static Boolean IsDirtyEntity(this ISession session, Object entity)

    {

        ISessionImplementor sessionImpl = session.GetSessionImplementation();

        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;

        EntityEntry oldEntry = persistenceContext.GetEntry(entity);

        String className = oldEntry.EntityName;

        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

 

        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 = oldState.Select((o, i) => (oldState [ i ] == currentState [ i ]) ? -1 : i).Where(x => x >= 0).ToArray();

 

        return (dirtyProps != null);

    }

 

    public static Boolean IsDirtyProperty(this ISession session, Object entity, String propertyName)

    {

        ISessionImplementor sessionImpl = session.GetSessionImplementation();

        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;

        EntityEntry oldEntry = persistenceContext.GetEntry(entity);

        String className = oldEntry.EntityName;

        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

 

        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);

        Int32 index = Array.IndexOf(persister.PropertyNames, propertyName);

 

        Boolean isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;

 

        return (isDirty);

    }

 

    public static Object GetOriginalEntityProperty(this ISession session, Object entity, String propertyName)

    {

        ISessionImplementor sessionImpl = session.GetSessionImplementation();

        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;

        EntityEntry oldEntry = persistenceContext.GetEntry(entity);

        String className = oldEntry.EntityName;

        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);


        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);

        Int32 index = Array.IndexOf(persister.PropertyNames, propertyName);

 

        Boolean isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;

 

        return ((isDirty == true) ? oldState [ index ] : currentState [ index ]);

    }

}

 

Recent Comments

By: Ricardo Peres Posted on 06-07-2011 10:31

@Jaguar:

Yes, that is by design: a non-mutable entity will never be saved back.

By: Ricardo Peres Posted on 06-07-2011 10:30

@a_rasekh:

If it comes from a different session, there's no way to know if it is dirty. The only way is to update the database with the current state of the object (Merge) or update the object with the current state of the database (Refresh).

By: Jaguar Posted on 04-05-2011 6:08

Actually is you set mutable="false" on an entity the LoadedState property will always be null which is a bummer

By: Eduard Stanculet Posted on 02-18-2011 5:03

I have the same problem with OldEntity is null

I think i am in a different session

By: a_rasekh Posted on 09-01-2010 4:03

Hi there,

I load an object in a session, then close the session.

after manipulation object in UI, I want to save it if it is dirty.

but with your method I can't do it.

How I can chek dirty in another session?

View All
Powered by Community Server (Commercial Edition), by Telligent Systems