2017-02-17 23 views
1

Я внедрил прослушиватель событий для операций аудита над моими объектами. Например, я сделал один для PreInsertEventListener под названием HibernatePreInsert. Кроме того, прочитав здесь, в stackoverflow, я сконфигурировал Integrator под названием HibernateIntegrator. Поскольку я использую Hibernate 4 и весну 4, я создал файл в META-INF/services с именем com.dacasals.raspertwo.interceptors.HibernateInterceptor, и там я добавил класс интегратора, как это рекомендовано в Интернете, а также здесь. Но когда я запускаю свое приложение и вставляю новый элемент, ничего не происходит, даже сообщения моего HibernatePrePersist не отображаются. Это первый случай, когда я пытаюсь использовать Hibernate EventListeners, и я не знаю, что может быть неправильным.Слушатель событий не работает в спящем режиме?

Вот и пример из классов, участвующих в моей проблеме, а также файловой структуры:

Слушатель:

public class HibernatePreInsert implements PreInsertEventListener{ 
    private static final long serialVersionUID = 1L; 
    static final Logger logger = LoggerFactory.getLogger(HibernatePreInsert.class); 

    @Override 
    public boolean onPreInsert(PreInsertEvent event) { 
     if(event.getEntity() instanceof Person){ 
      //display a message to know if this works or not 
      logger.info("It works"); 
     } 
     return false; 
    } 
} 

Интегратор:

public class HibernateIntegrator implements Integrator{ 

    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry){ 
     final EventListenerRegistry registry = serviceRegistry.getService(EventListenerRegistry.class); 

     HibernatePreInsert listener = new HibernatePreInsert(); 

     registry.prependListeners(EventType.PRE_INSERT, listener); 
    } 

    @Override 
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, 
      SessionFactoryServiceRegistry serviceRegistry) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { 
     // TODO Auto-generated method stub 

    } 

} 

The файла com.dacasals .raspertwo.interceptors.HibernateInterceptor:

com.dacasals.raspertwo.interceptors.HibernateInterceptor 

Заранее спасибо.

EDITED: Я сделал ошибку во время записи. Я использую Hibernate 5, а не 4.

+0

Какова цель вашего слушателя? Вы хотите установить значения для самой сущности или хотите вставить строку в другую таблицу? – Naros

+0

Я хочу сохранить в моей базе данных о произошедшем событии. Например, если новый человек вставлен, я хочу сохранить временную метку выполняемой операции. Я пытался сделать этот простой пример по методу onPreInsert, но ничего не произошло, тогда я отобразил сообщение и понял, что ничего не происходит. – Ethan

+0

Я предполагаю, что вы просто импортируете зависимость «hibernate-core» с Hibernate 4 и не используете зависимость «hibernate-entitymanager» и работаете с «SessionFactory». Это правильное предположение? – Naros

ответ

4

Я получил своих слушателей, чтобы работать без использования метода, который я нашел раньше. Вместо того, чтобы определять файл с сервисом, я создал новый класс, где я зарегистрировать свои реализованные Слушатель событий, как это:

@Component общественного класс EscuchadorGeneral {

@PersistenceUnit 
private EntityManagerFactory emf; 

@Inject 
private InsertEvent insert; 

@Inject 
private UpdateEvent update; 

@Inject 
private DeleteEvent delete; 

@PostConstruct 
protected void init(){ 
    SessionFactoryImpl sF = emf.unwrap(SessionFactoryImpl.class); 
    EventListenerRegistry registry = sF.getServiceRegistry().getService(EventListenerRegistry.class); 
    registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(insert); 
    registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(update); 
    registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener(delete); 
} 

}

А теперь я может слушать, когда какой-либо из моих сущностей вставлен, обновлен или удален. Я надеюсь, что это решение будет работать и для других разработчиков.

2

Поскольку все, что вы хотите сделать, это манипулировать сущностью, связанной с событием, я бы отстаивал здесь использование @PrePersist.

Вы можете обмануть Hibernate, чтобы по-прежнему запускать обратные вызовы интегратора JPA, даже если приложение не использует никаких функций JPA и продолжает использовать собственную конфигурацию SessionFactory.

Для Hibernate до 5.2 вам необходимо убедиться, что вы также включили соответствующий вариант hibernate-entitymanager в свой путь к классам зависимостей, который соответствует той же версии вашей зависимости hibernate-core. Для Hibernate 5.2 и выше все, что вам нужно включить, это hibernate-core, которые вы, очевидно, уже используете.

Далее следует установить META-INF/services/org.hibernate.integrator.spi.Integrator.

Для Hibernate уровня до 4,2 необходимо добавить:

org.hibernate.ejb.event.JpaIntegrator

Для Hibernate 4.3 и 5.x, вам нужно добавить:

org.hibernate.jpa.event.spi.JpaIntegrator

Теперь вы можете использовать обратный вызов @PrePersist, даже если ваша конфигурация не загружает JPA EntityManager.

После того как вы портируете приложение на использование JPA специально, вы можете в конечном итоге удалить эту конфигурацию интегратора, поскольку построенный JPA EntityManager автоматически зарегистрирует и выполнит эти обратные вызовы.

UPDATE

Если вы решили, что вы хотите использовать Hibernate EventListener, я хотел бы убедиться, как integrate методы регистрации этого слушателя. Я думаю, что тот, который вы реализовали, остался для устаревших контрактов, но я считаю, что более поздние версии Hibernate используют другую подпись, которую вы еще не реализовали. Вот почему ваш слушатель не срабатывает.

+0

Я буду искать реализацию второго метода 'integrate'. Я прочитал ваш ответ, и я пробовал подход аннотаций, но на этот раз мне это не нужно. Я пытаюсь сделать это с помощью EvenListeners. – Ethan