Interceptor接口提供了从会话(session)回调(callback)应用程序(application)的机制, 这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其 属性。一个可能的用途,就是用来跟踪审核(auditing)信息。例如:下面的这个拦截器,会在一个实现了 Auditable接口的对象被创建时自动地设置createTimestamp属性,并在实现了 Auditable接口的对象被更新时,同步更新lastUpdateTimestamp属性。


你可以直接实现Interceptor接口,也可以(最好)继承自EmptyInterceptor。  



拦截器可以有两种:Session范围内的,和SessionFactory范围内的。 

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;

    }

  

}

当使用某个重载的SessionFactory.openSession()使用Interceptor作为参数调用打开一个session的时候,就指定了Session范围内的拦截器。 


 Session session = sf.openSession( new AuditInterceptor() );


或在配置文件中加:


<bean id="sessionFactory" class="cn.sh.cares.framework.spring.annotationSessionFactoryBean">

<property name="dataSource" ref="ppcDataSource"/>

<!--<property name="lobHandler" ref="lobHandler"/>-->

<property name="annotatedClassesLocations">

<list>

<value>classpath*:</value>

</list>

</property>

<property name="hbmLocations">

<list>

<value>classpath*:</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">cn.sh.cares.framework.dao.hibernate.OracleDialect</prop>

<prop key="hibernate.format_sql">true</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.use_sql_comments">false</prop>

<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

<prop key="hibernate.cache.use_query_cache">true</prop>

<prop key="hibernate.cache.use_second_level_cache">true</prop>

<prop key="hibernate.jdbc.batch_size">20</prop>

<prop key="hibernate.jdbc.fetch_size">20</prop>

</props>

</property>

<property name="entityInterceptor">

<bean id ="auditInterceptor" class="cn.sh.cares.framework.dao.hibernate.AuditInterceptor" />

</property>