Перехватчик Hibernate и прослушиватели событий

Интересно, можно ли узнать, что спящий режим действительно сделал с базой данных (т.е. зафиксировал изменения). Я хотел бы уведомить другой процесс о некоторых изменениях.

Я предполагаю, что EventType POST_COMMIT_DELETE, POST_COMMIT_UPDATE и POST_COMMIT_INSERT должны делать, но с точно нулевой документацией это только предположение. Может кто-нибудь подтвердить? Я что-то не хватает?

Я также не уверен, как получить то, что действительно написано. PostInsertEvent содержит как Object entity, так и Object[] state, какой из двух я должен доверять?


Вопрос: я не использую ни XML, ни Spring, ни JPA, просто Configuration и buildSessionFactory. Это действительно так, как должны регистрироваться слушатели?

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

Я спрашиваю, как его 1. зависит от детали реализации, 2 абсолютно уродливый, 3. почти совершенно не узнаваемый.

Ответы

Ответ 1

Да, можно уведомить другой процесс (например: Аудит) после внесения определенных изменений в БД. То есть делать некоторые вещи сразу после транзакции JDBC (Hibernate обертывает транзакцию JDBC) с помощью пользовательских перехватчиков и событий для спящего режима.

Вы можете создать свой собственный класс перехватчиков, расширив его с помощью класса EmptyInterceptor спящего режима. И путем переопределения метода afterTransactionCompletion (Transaction tx) EmptyInterceptor для выполнения определенных задач после совершения транзакции.

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

Система Событие может использоваться дополнительно или в качестве замены для перехватчиков.

Ниже перечислены несколько способов выполнения определенной задачи после завершения/совершения транзакции.

1.Implement AfterTransactionCompletionProcess из пакета org.hibernate.action и реализуйте метод ниже. документация

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

В противном случае вы можете расширить класс CustomDeleteAction с помощью EntityDeleteAction и переопределить вышеупомянутый метод doAfterTransactionCompletion. документация

2. Внедрение PostDeleteEventListener и использование EventType.POST_COMMIT_DELETE для удаления сообщения.
Реализацией PostInsertEventListener и используя EventType.POST_COMMIT_INSERT для вставки post.
Реализовав PostUpdateEventListener и используя EventType.POST_COMMIT_UPDATE для пост-обновления.
Вот несколько примеров PostDeleteEventListener , PostUpdateEventListener и PostInsertEventListener.


Object entity PostInsertEvent предоставляет объект, участвующий в операции с базой данных.

Object[] state PostInsertEvent возвращает источник события сеанса для этого события. Это базовый сеанс, с которого было создано это событие.
Ниже ссылки содержит документацию для членов PostInsertEvent.

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


Регистрация прослушивателей событий. Ниже класс MyIntegrator показывает 3 способа для регистрации прослушивателей событий.

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 );
}
}

Следовательно, регистрация слушателей на событие зависит от деталей реализации.