Hibernate拦截器和事件监听器 [英] Hibernate interceptor and event listeners

查看:488
本文介绍了Hibernate拦截器和事件监听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能找出hibernate对数据库做了些什么(即,已提交的更改)。我想通知另一个进程在某些变化。



我猜测 EventType s POST_COMMIT_DELETE POST_COMMIT_UPDATE POST_COMMIT_INSERT 应该这样做,但只给出零文档,这只是一个猜测。有人可以确认吗?我错过了什么?



我也不确定如何获得真正写的东西。 PostInsertEvent 包含对象实体对象[]状态 ,我应该信任哪两个?






一个问题:我没有使用XML,没有使用Spring,没有JPA,只需配置 buildSessionFactory 。这是真正的听众应该注册的方式吗?

pre $ EventListenerRegistry registry =((SessionFactoryImpl)sessionFactory)
.getServiceRegistry( )
.getService(EventListenerRegistry.class);
registry.appendListeners(....);

我问的是1.依赖于实现细节,2完全丑陋,3.接近完全不可发现的。 在数据库中进行了某些更改后。这是在使用Hibernate的自定义拦截器事件提交JDBC事务(Hibernate封装JDBC事务)后立即执行某些事情。



您可以通过将hibernate的 EmptyInterceptor 类进行扩展来创建自己的自定义拦截器类。并且通过覆盖EmptyInterceptor的afterTransactionCompletion(Transaction tx)方法在事务提交后执行某些任务。

  public class AuditLogInterceptor扩展了EmptyInterceptor {
@Override
public void afterTransactionCompletion(Transaction tx){
System.out.println(事务完成后的任务);


$ / code $ / pre

$ hr

拦截器可以使用 Event 系统作为补充或替代。

以下列出了事务处理完成/提交后执行某些任务的几种方法



1 .Implement AfterTransactionCompletionProcess 接口来自org.hibernate.action包并实现以下方法。 文档

  void doAfterTransactionCompletion(布尔成功,SessionImplementor会话){
//完成事务后执行封装在这里的任何处理。





$ b

否则,可以使用 EntityDeleteAction 并覆盖上面的doAfterTransactionCompletion方法。 文档



2 。通过实现 PostDeleteEventListener 并使用 EventType.POST_COMMIT_DELETE 进行后删除。

通过实现 PostInsertEventListener 并使用 EventType.POST_COMMIT_INSERT 进行插入。

通过实现 PostUpdateEventListener ,并使用 EventType.POST_COMMIT_UPDATE 进行更新。

以下是几个 PostDeleteEventListener
PostUpdateEventListener PostInsertEventListener






<$ PostInsertEvent的c $ c> Object entity 给出数据库操作涉及的实体。

PostInsertEvent的 Object []状态返回此事件的会话事件源。这是生成此事件的底层会话。

下面的链接包含PostInsertEvent成员的文档。



http://mausch.github.io/nhibernate-3.2.0GA/ html / 6deb23c7-79ef-9599-6cfd-6f45572f6894.htm




注册事件侦听器:下面的MyIntegrator类显示 3种方式来注册事件侦听器。


$ b

  public class MyIntegrator implements org.hibernate.integrator.spi.Integrator {

public void integrate(配置配置,SessionFactoryImplementor或sessionFactory,SessionFactoryServiceRegistry serviceRegistry){
//如您所料,EventListenerRegistry是与事件监听器被注册
//这是一个服务,所以我们使用服务注册表
final Even来查找它tListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

//如果您希望自定义确定和处理重复侦听器,则必须添加org.hibernate.event.service.spi的
//实现。 DuplicationStrategy合同就像这样
eventListenerRegistry.addDuplicationStrategy(myDuplicationStrategy);

// EventListenerRegistry定义了3种注册监听器的方法:
// 1)该表单用
eventListenerRegistry.setListeners(EventType.AUTO_FLUSH,myCompleteSetOfListeners)覆盖任何现有的注册。
// 2)此表单将指定的侦听器添加到侦听器链的开头
eventListenerRegistry.prependListeners(EventType.AUTO_FLUSH,myListenersToBeCalledFirst);
// 3)此表单将指定的侦听器添加到侦听器链的末尾
eventListenerRegistry.appendListeners(EventType.AUTO_FLUSH,myListenersToBeCalledLast);






$ b因此,监听器注册一个事件取决于实现细节。


I wonder if it's possible to find out what hibernate really did to the database (i.e., committed changes). I'd like to notify another process on certain changes.

I guess that the EventTypes POST_COMMIT_DELETE, POST_COMMIT_UPDATE and POST_COMMIT_INSERT should do, but given exactly zero documentation, it's only a guess. Can someone confirm? Am I missing any?

I'm also unsure about how to obtain what gets really written. The PostInsertEvent contains both Object entity and Object[] state, which of the two should I trust?


A side question: I'm using no XML, no Spring, no JPA, just Configuration and buildSessionFactory. Is this really the way listeners should be registered?

 EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory)
    .getServiceRegistry()
    .getService(EventListenerRegistry.class);
registry.appendListeners(....);

I'm asking as its 1. dependent on an implementation detail, 2 totally ugly, 3. nearly perfectly undiscoverable.

解决方案

Yes, it is possible to notify another process(For Example: Auditing) after committing certain changes in the DB. That is to do certain things right after the JDBC transaction(Hibernate wraps JDBC transaction ) is committed using Custom Interceptors and Events of Hibernate.

You can create your own custom interceptor class by extending it by EmptyInterceptor class of hibernate. And by overriding the below afterTransactionCompletion(Transaction tx) method of EmptyInterceptor to do certain tasks after the transaction has been committed.

public class AuditLogInterceptor extends EmptyInterceptor {
 @Override
 public void afterTransactionCompletion(Transaction tx) {
    System.out.println("Task to do after transaction ");
 }
}


The Event system can be used in addition, or as a replacement, for interceptors.

Below listed are few ways to perform certain task after transaction event is completed/committed

1.Implement AfterTransactionCompletionProcess interface from org.hibernate.action package and implement the below method. documentation

void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
      //Perform whatever processing is encapsulated here after completion of the transaction.
}      

Otherwise, you can extend your CustomDeleteAction class with EntityDeleteAction and override the above doAfterTransactionCompletion method. documentation

2.By Implementing PostDeleteEventListener and using EventType.POST_COMMIT_DELETEfor post delete.
By Implementing PostInsertEventListener and using EventType.POST_COMMIT_INSERTfor post insert.
By Implementing PostUpdateEventListener and using EventType.POST_COMMIT_UPDATEfor post update.
Here are few examples of PostDeleteEventListener , PostUpdateEventListener and PostInsertEventListener.


The Object entity of PostInsertEvent gives the entity involved in the database operation.

The Object[] state of PostInsertEvent returns the session event source for this event. This is the underlying session from which this event was generated.
Below link contains the documentation for PostInsertEvent Members.

http://mausch.github.io/nhibernate-3.2.0GA/html/6deb23c7-79ef-9599-6cfd-6f45572f6894.htm


Registering event listeners: Below MyIntegrator class shows 3 ways to register event listeners.

public class MyIntegrator implements org.hibernate.integrator.spi.Integrator {

public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
    // As you might expect, an EventListenerRegistry is the thing with which event listeners are registered  
    // It is a service so we look it up using the service registry
    final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

    // If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an
    // implementation of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
    eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy );

    // EventListenerRegistry defines 3 ways to register listeners:
    //     1) This form overrides any existing registrations with
    eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, myCompleteSetOfListeners );
    //     2) This form adds the specified listener(s) to the beginning of the listener chain
    eventListenerRegistry.prependListeners( EventType.AUTO_FLUSH, myListenersToBeCalledFirst );
    //     3) This form adds the specified listener(s) to the end of the listener chain
    eventListenerRegistry.appendListeners( EventType.AUTO_FLUSH, myListenersToBeCalledLast );
}
}

Hence, Listeners registration to a event is dependent on implementation detail.

这篇关于Hibernate拦截器和事件监听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆