事件监听是JDK中常见的一种模式。 Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会调用监听器类中的事件处理方法。在某些功能的设计中,既可以使用Hibernate的拦截器实现,也可以使用Hibernate的事件监听来实现。 

Hibernate 定义了多个事件涵盖了持久化过程中的不同生命同期,即Session对象中的第一个方法均分别对应事件。调用某个方法时就会触发相应的事件,并被预先设置的监听器收到及处理。

  

事件与监听器接口的对应关系

事件类型

对应的监听器接口

auto-flush

AutoFlushEventListener 

merge

MergeEventListener 

delete 

DeleteEventListener 

persist

PersistEventListener 

dirty-check

DirtyCheckEventListener

evict

EvictEventListener 

flush

FlushEventListener 

flush-entity

FlushEntityEventListener 

load

LoadEventListener 

load-collection

LoadCollectionEventListener 

lock

LockEventListener 

refresh

RefreshEventListener 

replicate

ReplicateEventListener 

save-update

SaveUpdateEventListener 

pre-load

PreLoadEventListener 

pre-update

PreUpdateEventListener 

pre-delete

PreDeleteEventListener 

pre-insert

PreInsertEventListener 

post-load

PostLoadEventListener 

post-update

PostUpdateEventListener 

post-delete

PostDeleteEventListener 

post-insert

PostInsertEventListener 

 

Hibernate中加载事件监听两种方式,一种是在hibernate.cfg.xml中进行加载,一种是在程序中进行加载

如下:自定义事件监听器LogPostLoadEventListener.java:

public class MyPostLoadEventListener implements PostLoadEventListener {
@Override
public void onPostLoad(PostLoadEvent arg0) {
System.out.println("Class:" + arg0.getEntity().getClass().getName());
}

}

 在hibernate.cfg.xml中加载:

1 <hibernate-configuration>
2
3 <session-factory>
4 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
5 <property name="connection.url">jdbc:mysql://localhost:3306/book</property>
6 <property name="connection.username">yuan</property>
7 <property name="connection.password">hanyuan9113</property>
8 <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
9 <property name="myeclipse.connection.profile">mysql</property>
10
11 <listener class="com.yun.MyPostLoadEventListener" type="post-load"/>
12 </session-factory>
13
14 </hibernate-configuration>


在程序中加载:

new Configuration();
cfg.setListener("post-load", new MyPostLoadEventListener());
cfg.configure();

事件监听与拦截器的比较:

事件监听与拦截器都可以拦截Session对象对持久化对象的操作动作,但是事件监听可以实现更加细化粒度上的拦截,同时还可以通过事件监听器对象获取所拦截的持久化对象修改前的状态值,并且能直接通过Event对象获取Session对象.