`
betafox
  • 浏览: 143029 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate的事件和拦截器体系

阅读更多

 

持久层框架底层的拦截器机制是对诸如Spring等业务管理容器拦截机制的有益补充,使得我们可以在更低层次、更广的对象范围上进行AOP操作(Spring虽然将Hibernate纳入到其容器管理的范围内,但是并没有途径实现对其实体对象的管理)。这样就允许实现某些通用的功能,以及允许对Hibernate功能进行扩展。

  1. 拦截器(Interceptors)

Interceptor接口提供了从会话(session)回调(callback)应用程序(application)的机制, 这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其 属性。

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

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

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

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

l         SessionFactory范围内的拦截器要通过Configuration中注册,而这必须在创建SessionFactory之前。在这种情况下,给出的拦截器会被这个SessionFactory所打开的所有session使用了,除非session打开时明确指明了使用的拦截器。SessionFactory范围内的拦截器,必须是线程安全的,因为多个session可能并发使用这个拦截器,要因此小心不要保存与session相关的状态

new Configuration().setInterceptor( new AuditInterceptor() );

spring配合使用时需要配置sessionFactory对象的entityInterceptor属性:

  1 <property name="entityInterceptor">

  2        <bean class="**.AuditTrailInterceptor"/>

  3        <bean class="**.AuditTrailInterceptor2"/>

  4  </property>

 

例如:

A、下面的这个拦截器,会在一个实现了 Auditable接口的对象被创建时自动地设置createTimestamp属性,并在实现了 Auditable接口的对象被更新时,同步更新lastUpdateTimestamp属性。

1 public class AuditInterceptor extends EmptyInterceptor {

  2

  3     private int updates;

  4     private int creates;

  5     private int loads;

  6

  7     public void onDelete(Object entity,

  8                          Serializable id,

  9                          Object[] state,

 10                          String[] propertyNames,

 11                          Type[] types) {

 12         // do nothing

 13     }

 14

 15     public boolean onFlushDirty(Object entity,

 16                                 Serializable id,

 17                                 Object[] currentState,

 18                                 Object[] previousState,

 19                                 String[] propertyNames,

 20                                 Type[] types) {

 21

 22         if (entity instanceof Auditable) {

 23             updates++;

 24             for (int i = 0; i < propertyNames.length; i++) {

 25                 if ("lastUpdateTimestamp".equals(propertyNames[i])) {

 26                     currentState[i] = new Date();

 27                     return true;

 28                 }

 29             }

 30         }

 31         return false;

 32     }

 33

 34     public boolean onLoad(Object entity,

 35                           Serializable id,

 36                           Object[] state,

 37                           String[] propertyNames,

 38                           Type[] types) {

 39         if (entity instanceof Auditable) {

 40             loads++;

 41         }

 42         return false;

 43     }

 44

 45     public boolean onSave(Object entity,

 46                           Serializable id,

 47                           Object[] state,

 48                           String[] propertyNames,

 49                           Type[] types) {

 50

 51         if (entity instanceof Auditable) {

 52             creates++;

 53             for (int i = 0; i < propertyNames.length; i++) {

 54                 if ("createTimestamp".equals(propertyNames[i])) {

 55                     state[i] = new Date();

 56                     return true;

 57                 }

 58             }

 59         }

 60         return false;

 61     }

 62

 63     public void afterTransactionCompletion(Transaction tx) {

 64         if (tx.wasCommitted()) {

 65             System.out.println("Creations: " + creates + ", Updates: " + updates+ "Loads: " + loads);

 66         }

 67         updates = 0;

 68         creates = 0;

 69         loads = 0;

 70     }

 71

 72 }

 

 

2.         事件系统(Event system)

如果需要响应持久层的某些特殊事件,你也可以使用Hibernate3的事件框架。 该事件系统可以用来替代拦截器,也可以作为拦截器的补充来使用。

基本上,Session接口的每个方法都有相对应的事件。比如 LoadEventFlushEvent,等等(可以查阅XML配置文件 DTD以及org.hibernate.event包来获得所有已定义的事件的列表)。

当某个方 法被调用时,Hibernate Session会生成一个相应的事件并激活所有配置好的事件监听器。被监听的方法所做的其实仅仅是激活监听器,“实际”的工作是由监听器完成的。你可以自由地选择实现一个自己定制的监听器:比如,实现并注册用来处理处理LoadEventLoadEventListener接口, 来处理所有的调用Sessionload()方法的请求。

监听器在运行时被实例化为单例(singleton)对象,也就是说,所有同类型的事件的处理共享同一个监听器实例,因此监听器不应该保存任何与请求相关的状态。

用户定制的监听器需要实现相关的事件监听器接口,或者从一个合适的基类继承(甚至是从Hibernate自带的默认事件监听器类继承,作者已经通过这些类的non-final定义给予我们这样的暗示和权利了)。

用户定制的监听器可以通过编程使用Configuration对象 来注册,也可以在HibernateXML格式的配置文件中进行声明(不支持在Properties格式的配置文件声明监听器)。 下面是一个用户定制的加载事件(load event)的监听器:

public class MyLoadListener implements LoadEventListener {

    // this is the single method defined by the LoadEventListener interface

    public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)

                          throws HibernateException {

       if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {

            throw MySecurityException("Unauthorized access");

       }

    }

}

 

除此之外你还需要修改一处配置,来告诉Hibernate,除了默认的监听器,还要附加选定的监听器。

<hibernate-configuration>

    <session-factory>

        ...

        <event type="load">

            <listener class="com.eg.MyLoadListener"/>

            <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>

        </event>

    </session-factory>

</hibernate-configuration>

看看用另一种方式,通过编程的方式来注册它。

Configuration cfg = new Configuration();

LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };

cfg.EventListeners().setLoadEventListeners(stack);

 

通过在XML配置文件声明而注册的监听器不能共享实例。如果在多个<listener/>节点中使用 了相同的类的名字,则每一个引用都将会产生一个独立的实例。如果你需要在多个监听器类型之间共享 监听器的实例,则你必须使用编程的方式来进行注册。

 

为什么我们实现了特定监听器的接口,在注册的时候还要明确指出我们要注册哪个事件的监听器呢? 这是因为一个类可能实现多个监听器的接口。在注册的时候明确指定要监听的事件,可以让启用或者禁用对某个事件的监听的配置工作简单些。

 

当与Spring配合使用时同样需要配置sessionFactoryeventListener属性。

分享到:
评论
5 楼 raymond2006k 2008-11-24  
betafox 写道
关于拦截器还有一个例子一直加不进去,只要加上那个例子文章一提交就出错!


可以附在回复里。
文章写的不错,很有用的资料。
4 楼 liucl_tiger 2008-11-07  
我也正学习这个!
3 楼 taupo 2008-09-02  
我们的项目中用拦截器来删除帖子的附件。。。
我感觉这是一种比较好的利用拦截器

2 楼 betafox 2008-08-28  
希望能发掘一下大家对hibernate拦截器的使用。
1 楼 betafox 2008-08-28  
关于拦截器还有一个例子一直加不进去,只要加上那个例子文章一提交就出错!

相关推荐

    hibernate 体系结构与配置 参考文档(html)

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    Hibernate框架参考文档

    12. 拦截器与事件(Interceptors and events); 13. 批量处理(Batch processing; 14. HQL: Hibernate查询语言; 15. 条件查询(Criteria Queries); 16. Native SQL查询; 17. 过滤数据; 18. XML映射; 19. 提升性能; 20. ...

    Hibernate+中文文档

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    hibernate3.2中文文档(chm格式)

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    HibernateAPI中文版.chm

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    hibernate 教程

    拦截器(Interceptors) 9.10. 元数据(Metadata) API 10. 事务和并行(Transactions And Concurrency) 10.1. 配置,会话和工厂(Configurations, Sessions and Factories) 10.2. 线程和连接(Threads ...

    Hibernate中文详细学习文档

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    Hibernate 中文 html 帮助文档

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    Hibernate 3.6.0.Final Reference PDF 手册

    第 14 章 拦截器与事件(Interceptors and events) 第 15 章 批量处理(Batch processing) 第 16 章 HQL: Hibernate 查询语言 第 17 章 条件查询(Criteria Queries) 第 18 章 Native SQL 查询 第...

    Hibernate教程

    13. 拦截器与事件(Interceptors and events) 13.1. 拦截器(Interceptors) 13.2. 事件系统(Event system) 13.3. Hibernate的声明式安全机制 14. 批量处理(Batch processing) 14.1. 批量插入(Batch inserts) ...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    hibernate

    拦截器(Interceptors) 9.10. 元数据(Metadata) API 10. 事务和并行(Transactions And Concurrency) 10.1. 配置,会话和工厂(Configurations, Sessions and Factories) 10.2. 线程和连接(Threads ...

    hibernate3.04中文文档.chm

    13. 拦截器与事件(Interceptors and events) 13.1. 拦截器(Interceptors) 13.2. 事件系统(Event system) 13.3. Hibernate的声明式安全机制 14. 批量处理(Batch processing) 14.1. 批量插入(Batch ...

    hibernate 框架详解

    13. 拦截器与事件(Interceptors and events) 13.1. 拦截器(Interceptors) 13.2. 事件系统(Event system) 13.3. Hibernate的声明式安全机制 14. 批量处理(Batch processing) 14.1. 批量插入(Batch inserts...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    Hibernate参考文档

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

Global site tag (gtag.js) - Google Analytics