hibernate 拦截hibernate事件

拦截hibernate事件:
例子实现审计日志:
1、创建标记接口
用这个接口给所有应该子被自动审计的持久化类做上标记:
  1. /**
  2. * 例子实现审计日志:
  3. * 1、创建标记接口
  4. * 用这个接口给所有应该子被自动审计的持久化类做上标记
  5. * @author partner4java
  6. *
  7. */
  8. publicinterfaceAuditable {
  9. publicLong getId();
  10. }

2、创建和映射日志记录
创建新的持久化类AuditLogRecord。这个类标识你想要的审计数据库表中记入日志信息:
  1. /**
  2. * 2、创建和映射日志记录
  3. * 创建新的持久化类AuditLogRecord。这个类标识你想要的审计数据库表中记入日志信息
  4. * @author partner4java
  5. *
  6. */
  7. publicclassAuditLogRecordimplementsSerializable {
  8. privateLong auditLogId;
  9. privateString message;
  10. privateLong entityId;
  11. privateClass entityClass;
  12. privateLong userId;
  13. privateDate created;
  1. <classname="AuditLogRecord"table="Audit_Log_Record"mutable="false">
  2. <id name="auditLogId"column="audit_Log_Id"type="long">
  3. <generatorclass="native"/>
  4. </id>
  5. <property name="message"length="200"></property>
  6. <property name="entityId"column="entity_Id"type="long"not-null="true"></property>
  7. <property name="entityClass"column="entity_Class"type="class"not-null="true"></property>
  8. <property name="userId"column="user_Id"type="long"></property>
  9. <property name="created"type="java.util.Date"not-null="true"update="false"></property>
  10. </class>


3、编写拦截器
当调用save时(),应该自动调用logEvent()方法。利用hibernate完成实现Interceptor接口。
  1. /**
  2. * 3、编写拦截器
  3. * 当调用save时(),应该自动调用logEvent()方法。利用hibernate完成实现Interceptor接口。
  4. * @author partner4java
  5. *
  6. */
  7. publicclassAuditLogInterceptorextendsEmptyInterceptor {
  8. privateSession session;
  9. privateLong userId;
  10. privateSet inserts =newHashSet();
  11. privateSet updates =newHashSet();
  12. publicvoidsetSession(Session session) {
  13. this.session = session;
  14. }
  15. publicvoidsetUserId(Long userId) {
  16. this.userId = userId;
  17. }
  18. /**
  19. * 每当hibernate侦测到脏对象时,就调用
  20. * Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected currentState, which will be propagated to both the database and the persistent object. Note that not all flushes end in actual synchronization with the database, in which case the new currentState will be propagated to the object, but not necessarily (immediately) to the database. It is strongly recommended that the interceptor not modify the previousState.
  21. */
  22. publicbooleanonFlushDirty(Object entity, Serializable id,
  23. Object[] currentState, Object[] previousState,
  24. String[] propertyNames, Type[] types) {
  25. if(entityinstanceofAuditable){
  26. inserts.add(entity);
  27. }
  28. returnfalse;
  29. }
  30. /**
  31. * 保存实体时
  32. * Called before an object is saved. The interceptor may modify the state, which will be used for the SQL INSERT and propagated to the persistent object.
  33. */
  34. publicbooleanonSave(Object entity, Serializable id, Object[] state,
  35. String[] propertyNames, Type[] types) {
  36. if(entityinstanceofAuditable){
  37. updates.add(entity);
  38. }
  39. returnfalse;
  40. }
  41. /**
  42. * hibernate在执行了把持久化上下文实现为与数据库同步的SQL之后调用他
  43. * Called after a flush that actually ends in execution of the SQL statements required to synchronize in-memory state with the database
  44. */
  45. publicvoidpostFlush(Iterator entities)throwsCallbackException{
  46. try{
  47. for(Iterator it = inserts.iterator();it.hasNext();){
  48. Auditable auditable = (Auditable) it.next();
  49. AuditLog.logEvent("create",auditable,userId,session.connection());
  50. }
  51. for(Iterator it = updates.iterator();it.hasNext();){
  52. Auditable auditable = (Auditable) it.next();
  53. AuditLog.logEvent("update",auditable,userId,session.connection());
  54. }
  55. }finally{
  56. inserts.clear();
  57. updates.clear();
  58. }
  59. }
  60. }


4、启用拦截器
第一次打开会话时,你需要把Interceptor分配到Hibernate Session:
  1. publicclassItemDao {
  2. publicvoidsaveDao(Item item){
  3. AuditLogInterceptor interceptor =newAuditLogInterceptor();
  4. Session session = getSessionFactory().openSession(interceptor);
  5. Transaction tx = session.beginTransaction();
  6. interceptor.setSession(session);
  7. interceptor.setUserId(1L);
  8. session.save(item);
  9. tx.commit();
  10. session.close();
  11. }
  12. }

AuditLog:
  1. publicclassAuditLog {
  2. publicstaticvoidlogEvent(String message, Auditable auditable,
  3. Long userId, Connection connection) {
  4. Session session = getSessionFactory().openSession(connection);
  5. try{
  6. AuditLogRecord auditLogRecord =newAuditLogRecord(message, auditable.getId(),
  7. auditable.getClass(), userId,newDate());
  8. session.save(auditLogRecord);
  9. session.flush();
  10. }finally{
  11. session.close();
  12. }
  13. }
  14. }


调用:
  1. ItemDao itemDao =newItemDao();
  2. itemDao.saveDao(newItem("hello2"));
  3. //hibernate打印:
  4. //Hibernate: insert into ITEM (ITEM_NAME) values (?)
  5. //Hibernate: insert into Audit_Log_Record (message, entity_Id, entity_Class, user_Id, created) values (?, ?, ?, ?, ?)







内核事件系统:
Hibernate3.x与Hibernate2.x相比,是内核持久化引擎实现的一项重要的重新设计。新内核引擎基于一个事件/监听器的模型。
(默认方法通过DefaultLoadEventListener处理)
监听器实际上应该被认为是单例,意味着他们在请求之间被共享,因而不应该把任何事务相关的状态保存为实例变量。


cfg.getEventListeners().setLoadEventListeners(listenerStack);

hibernate:

...
<event type="load">
<listener class="mylis.."/>
</event>
</session-factory>

JPA:
...
<property name="hiernate.ejb.event.load" value="mylis...,..."/>
</properties>
</persistence-unit>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值