Saturday 13 September 2014

Hibernate Interceptors


Hibernate Interceptors

The Interceptor interface provides callbacks from the session to the application, allowing the application to inspect and/or manipulate properties of a persistent object before it is saved, updated, deleted or loaded. One possible use for this is to track auditing information. For example, the following Interceptor automatically sets the createTimestamp when an Auditable is created and updates the lastUpdateTimestamp property when an Auditable is updated. You can either implement Interceptor directly or extend EmptyInterceptor.

    
package org.hibernate.test;

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
public class AuditInterceptor extends EmptyInterceptor {
    private int updates;
    private int creates;
    private int loads;
    public void onDelete(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        // do nothing
    }
    public boolean onFlushDirty(Object entity,
        Serializable id,
        Object[] currentState,
        Object[] previousState,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            updates++;
            for (int i = 0; i < propertyNames.length; i++) {
                if ("lastUpdateTimestamp".equals(propertyNames[i])) {
                    currentState[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    public boolean onLoad(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            loads++;
        }
        return false;
    }
    public boolean onSave(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            creates++;
            for (int i = 0; i < propertyNames.length; i++) {
                if ("createTimestamp".equals(propertyNames[i])) {
                    state[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    public void afterTransactionCompletion(Transaction tx) {
        if (tx.wasCommitted()) {
            System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
        }
        updates = 0;
        creates = 0;
        loads = 0;
    }
}

And here's an explanation of the single callback methods:

Method       Explanation
findDirty      This method is be called when the flush() method is called on a Session object.
instantiate     This method is called when a persisted class is instantiated.
isUnsaved      This method is called when an object is passed to the saveOrUpdate() method/
onDelete      This method is called before an object is deleted.
onFlushDirty     This method is called when Hibernate detects that an object is dirty (ie. have been    
             changed) during a flush i.e. update operation.
onLoad       This method is called before an object is initialized.
onSave       This method is called before an object is saved.
postFlush      This method is called after a flush has occurred and an object has been updated in memory.
preFlush      This method is called before a flush

No comments:

Post a Comment