在Hibernate中,有两种方式可以捕获实体对象的GRUD操作并执行相应的处理

Hibernate回调(org.hibernate.classic.Lifecycle接口):

//Provides callbacks from the Session to the persistent object.
//Persistent classes may implement this interface but they are not
//required to.
//If a CallbackException is thrown, the operation is vetoed and the
//exception is passed back to the application.
public interface Lifecycle { //If onSave(), onUpdate() or onDelete() return VETO,
//the operation is silently vetoed.
public static final boolean VETO = true;
public static final boolean NO_VETO = false; //Called just before the object is saved
public boolean onSave(Session s) throws CallbackException; //Called when an entity is passed to Session.update().
//This method is not called every time the object's
//state is persisted during a flush.
public boolean onUpdate(Session s) throws CallbackException; //Called just before an object is deleted
public boolean onDelete(Session s) throws CallbackException; //Called just after an object is loaded
public void onLoad(Session s, Serializable id);
}

需要注意的地方:

1,如果onSave()、onUpdate()、onDelete()方法返回VOTE(true)或者在以上方法中抛出了CallbackException异常,操作将会停止而不会调用之后的Session.save()、Session.update()、Session.delete()方法

2,并不是每次调用Session.update()方法之前都会调用onUpdate()方法

3,调用Session.get()方法会直接返回实体对象,故在调用该方法后会立即调用onload()方法,而调用Session.load()方法返回的是实体对象的代理,故在调用该方法后不会立即调用onload()方法,对象在第一次使用时才会真正加载,而在对象真正加载完成之后才会调用onload()方法

4,不能直接使用方法中的Session对象,该方法是由当前Session负责调用,如果在这些方法中又调用当前Session进行持久化,将导致Session内部状态混乱

在onSave()方法中调用Session.save()方法将会导致死循环,但是在onSave()方法中执行Session.update()方法却没有报异常,不过通常方法只负责记录日志,数据合法性校验等简单工作,不会在这里再次调用Session对象完成数据持久化,故不需考虑太多

提到Lifecycle接口,通常也要提到Validatable接口(org.hibernate.classic.Validatable):

//Implemented by persistent classes with invariants that must
//be checked before inserting into or updating the database.
public interface Validatable { //Validate the state of the object before persisting it.
//If a violation occurs, throw a ValidationFailure.
//This method must not change the state of the object by
//side-effect.
public void validate() throws ValidationFailure;
}

只有在对象插入和对象更新时才会调用validate()方法对对象数据合法性进行校验

public class User implements Serializable,Lifecycle,Validatable{
private Integer id;
private String name;
private Integer age;
private static final long serialVersionUID = 1L; public User(){} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public boolean onSave(Session s) throws CallbackException {
System.out.println("********on save********");
System.out.println("id :" + id);
System.out.println("name :" + name);
System.out.println("age :" + age);
return Lifecycle.NO_VETO;
} @Override
public boolean onUpdate(Session s) throws CallbackException {
System.out.println("********on update********");
System.out.println("id :" + id);
System.out.println("name :" + name);
System.out.println("age :" + age);
return Lifecycle.VETO;
} @Override
public boolean onDelete(Session s) throws CallbackException {
System.out.println("********on delete********");
throw new CallbackException("Delete operation is not allowed!");
} @Override
public void onLoad(Session s, Serializable id) {
System.out.println("********on load********");
System.out.println("id :" + id);
} @Override
public void validate() throws ValidationFailure {
System.out.println("~~~~~~~~valid~~~~~~~~");
if(id < 0)
throw new ValidationFailure("Illegal id!");
if(name == null || name.equals(""))
throw new ValidationFailure("Illegal name!");
if(age < 0 || age > 150)
throw new ValidationFailure("Illegal age!");
}
}

由于这种方式对POJO带有侵入性,所以不建议使用

Hibernate拦截(org.hibernate.Interceptor接口):

接口定义了非常多的方法,基本上通过命名就可以看出其功能,就不一一介绍了

不建议直接继承Interceptor接口,更好的方式是继承EmptyInterceptor类,并重写需要的方法,EmptyInterceptor接口如下:

public class EmptyInterceptor implements Interceptor,
Serializable { public static final Interceptor INSTANCE =
new EmptyInterceptor(); protected EmptyInterceptor() {} public void onDelete(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {} public boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
return false;
} public boolean onLoad(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
return false;
} public boolean onSave(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
return false;
} public void postFlush(Iterator entities) {} public void preFlush(Iterator entities) {} public Boolean isTransient(Object entity) {
return null;
} public Object instantiate(String entityName, EntityMode entityMode,
Serializable id) {
return null;
} public int[] findDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
return null;
} public String getEntityName(Object object) {
return null;
} public Object getEntity(String entityName, Serializable id) {
return null;
} public void afterTransactionBegin(Transaction tx) {} public void afterTransactionCompletion(Transaction tx) {} public void beforeTransactionCompletion(Transaction tx) {} public String onPrepareStatement(String sql) {
return sql;
} public void onCollectionRemove(Object collection, Serializable key)
throws CallbackException {} public void onCollectionRecreate(Object collection, Serializable key)
throws CallbackException {} public void onCollectionUpdate(Object collection, Serializable key)
throws CallbackException {}
}

示例如下:

public class LogInterceptor extends EmptyInterceptor {

	private static final long serialVersionUID = 1L;

	@Override
public boolean onLoad(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
System.out.println(entity.getClass().getName() + " loaded.");
return false;
}
}

值得注意的是可以配置2种范围的拦截器

SessionFactory范围的拦截器:

由于多个Session可能并发的使用SessionFactoruy范围的拦截器,故该拦截器必须是线程安全的

LogInterceptor li = new LogInterceptor();
Configuration conf = new Configuration().setInterceptor(li);
SessionFactory sessionFactory = conf.configure().buildSessionFactory(); Session sess = sessionFactory.openSession();

Session范围的拦截器:

LogInterceptor li = new LogInterceptor();
Configuration conf = new Configuration();
SessionFactory sessionFactory = conf.configure().buildSessionFactory(); Session sess = sessionFactory.openSession(li);

Hibernate的回调与拦截的更多相关文章

  1. Ps回调函数.拦截驱动模块原理+实现.

    目录 一丶简介 二丶原理 1.原理 2.代码实现 3.效果 一丶简介 主要是讲解.内核中如何拦截模块加载的. 需要熟悉.内核回调的设置 PE知识. ShellCode 二丶原理 1.原理 原理是通过回 ...

  2. 再谈Delphi关机消息拦截 -- 之控制台程序 SetConsoleCtrlHandler(控制台使用回调函数拦截,比较有意思)

    这里补充一下第一篇文章中提到的拦截关机消息 Delphi消息拦截:http://blog.csdn.net/cwpoint/archive/2011/04/05/6302314.aspx 下面我再介绍 ...

  3. 笔记:Hibernate 拦截器和事件

    Hibernate 在执行持久化的过程中,应用程序通常无法参与其中,通过事件框架,Hibernate 允许应用程序能响应特定的内部事件,从而允许实现某些通用的功能,或者对 Hibernate 进行扩展 ...

  4. Hibernate学习---第十三节:hibernate过滤器和拦截器的实现

    一.hibernate 过滤器 1.在持久化映射文件中配置过滤器,代码如下: <?xml version="1.0"?> <!DOCTYPE hibernate- ...

  5. Atitit.hibernate体系结构大总结

    Atitit.hibernate体系结构大总结 1. 4.1 hibernate基础语义 80  4.1.1 configuration 80  4.1.2 sessionfactory 81  4. ...

  6. hibernate详解

    Hibernate原理与应用 主要内容 1.引入 2.安装配置 3.基本概念和CURD 4.HQL和Criteria 5.关联映射 6.继承映射 7.集合映射 8.懒加载 9.缓存 10.事务 11. ...

  7. 拦截器(Interceptor)与过滤器(Filter)的区别

    转自:https://www.jianshu.com/p/cf088baa9b04 过滤器,是在java web中将你传入的request.response提前过滤掉一些信息,或者提前设置一些参数.然 ...

  8. Struts2之过滤器和拦截器的区别

    刚学习Struts2这个框架不久,心中依然有一个疑惑未解那就是过滤器和拦截器的区别,相信也有不少人跟我一样对于这个问题没有太多的深入了解 那么下面我们就一起来探讨探讨 过滤器,是在java web中, ...

  9. 过滤器(servlet.filter)和拦截器(springmvc.interceptor)区别

    ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 ...

随机推荐

  1. 丁又专老师作业——Java检测代码

    package com.util; import java.io.*; import java.util.regex.Pattern; /** * 代码统计工具 * 统计某个java源文件或某个目录中 ...

  2. JavaWeb应用中重定向与跳转的区别

    针对JSP与Servlet: 两种重要的跳转: 1.request.getRequestDispatcher("地址").forward(ServletRequest, Servl ...

  3. 应用JConsole学习Java GC

    应用JConsole学习Java GC 关于Java GC的知识,好多地方都讲了很多,今天我用JConsole来学习一下Java GC的原理. GC原理 在我的上一篇中介绍了Java运行时数据区,在了 ...

  4. C# 索引器 学习

    转载原地址: http://www.cnblogs.com/lxblog/p/3940261.html 1.索引器(Indexer): 索引器允许类或者结构的实例按照与数组相同的方式进行索引.索引器类 ...

  5. POJ 1573 (13.10.11)

    Description A robot has been programmed to follow the instructions in its path. Instructions for the ...

  6. 再次理解JavaScript原型链和匿名函数

    <!--------------------------------------------- 1.演示匿名加载 2.js单进程执行流 3.原型链理解 a.__proto__:属性每个对象都有 ...

  7. zookeeper 系列

    ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂易出错的关键服务 ...

  8. ADO.NET 快速入门(四):从数据库填充 DataSet

    从数据库获取数据很容易,处理数据更容易.如果想要从数据库获取只进.只读的数据流结果集,你可以使用 DataReader 执行命令并且检索它.关于如何使用 DataReader,请参考:使用 OLE D ...

  9. 教你50招提升ASP.NET性能(二十六):对于开发人员的数据库性能技巧

    Database Performance Tips for Developers对于开发人员的数据库性能技巧 As a developer you may or may not need to go ...

  10. 2014广州Java岗位面试汇总

    本文记录了最近一些朋友提供的面试经历,真实数据,仅供广州求职的朋友参考.为行文方便,一律用主语”我“进行.部分词语可能造成读者不良反应,敬请留意. 1  广州沣首信息科技有限公司 公司所在区域相对较偏 ...