Hibernate : get the modified properties and their old values

Hibernate : get the modified properties and their old values

Imagine your IHM sends you a big POJO object which is already persisted. Are you going to let Hibernate flush the whole state of the entity without even knowing what has been changed ?

If you can do that, you are lucky. In real applications, it is often necessary to trigger some specific treatments if a property has been changed.

Actually, Hibernate does it all the time, so it has all the needed methods (publicly visibles) in order to know exactly the changes made to your pojo.

Here is the code in order to use those methods.

Get EntityPersister from SessionFactory

You must have a method getSessionFactory() which gives you the Hibernate SessionFactory. Then write a method which will return the entityPersister of your Pojo :

protected EntityPersister getEntityPersister() {
    SessionFactoryImplementor sessionFactoryImplementor = (SessionFactoryImplementor) getSessionFactory();
    return sessionFactoryImplementor.getEntityPersister(POJO.class.getName());
}

Get the databaseSnapshot of your object

With the entityPersister and your session casted as SessionImplementor, you can get the databaseSnapshot, which is an array of Objects, the persisted values of the properties of your pojo. You must have a getId() method on your pojo in order to get its primary key value.

EntityPersister entityPersister = getEntityPersister();
SessionImplementor sessionImplementor = (SessionImplementor) getSession();
PersistenceContext persistenceContext = sessionImplementor.getPersistenceContext();
Object[] databaseSnapshot = persistenceContext.getDatabaseSnapshot((Serializable) pojo.getId(), entityPersister);

Get the indexes of modified properties

entityPersister has a method findModified() which gives you an array of the index of the modified properties :

public int[] findPropertiesModified(POJO pojo) {
    EntityPersister entityPersister = getEntityPersister();
    SessionImplementor sessionImplementor = (SessionImplementor) getSession();
    PersistenceContext persistenceContext = sessionImplementor.getPersistenceContext();
    Object[] databaseSnapshot = persistenceContext.getDatabaseSnapshot((Serializable) pojo.getId(), entityPersister);
    Object[] propertyValues = entityPersister.getPropertyValues(pojo, getSession().getEntityMode());
    return entityPersister.findModified(databaseSnapshot, propertyValues, pojo, sessionImplementor);
}

Get the persisted value

The persisted value of the property is databaseSnapshot[index].

Get the name of the modified property

You can retrieve the name of the modified property from its index with the EntityMetamodel of your entity.

EntityMetamodel metamodel = entityPersister.getEntityMetamodel();
String[] properties = metamodel.getPropertyNames();

The name of the property is properties[index].

No comments.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>