Регистрация изменений сущностей в веб-приложении Java - PullRequest
5 голосов
/ 20 сентября 2010

У нас есть требование к нашему проекту, в котором нам нужно вести своего рода историю изменений, которые вносятся в определенные объекты в приложении. Приложение представляет собой веб-приложение Java, основанное на Struts, Spring и Hibernate. Какие подходы были использованы в этом случае?

  • Триггеры на соответствующих таблицах - одна из идей, но их нелегко обслуживать? и, возможно, они также не должны быть частью транзакций (это нормально, если триггеры не работают, но транзакции обновления сущности не должны завершаться неудачей).
  • Используйте AoP для этого, так как это междисциплинарная задача, но она должна быть очень детальной, так как при захвате только значений при изменении сущности. (Все правки не имеют соответствующих им различных методов ... многие правки происходят в одном методе Java).
  • Использовать прослушиватели событий Hibernate.

Существуют ли другие подходы для такого рода деятельности?

Ответы [ 2 ]

4 голосов
/ 20 сентября 2010

JBoss Envers поддерживает прослушивание и управление версиями - посмотрите.

3 голосов
/ 20 сентября 2010

Поскольку вы сказали

Все правки не имеют соответствующих им различных методов ... многие правки происходят в одном методе java

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

Сама документация Hibernate гласит:

Перехватчик Hibernate позволяет приложению проверять и / или манипулировать свойствамипостоянный объект перед его сохранением, обновлением, удалением или загрузкой. Одним из возможных применений для этого является отслеживание информации аудита.

Но там также говорится:

Убедитесь, что вы не сохраняете состояния, специфичные для сессии, поскольку несколько сеансов потенциально могут использовать этот перехватчик одновременно

Если вы используете управляемую Spring транзакцию, вы можете получить сеанс, привязанный к текущему потоку, используя sessionFactory.getCurrentSession ();

public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    if(entity instanceof SomeEntity) {
        Session session = sessionFactory.getCurrentSession();

См. getCurrentSession () документация

Если нет, вам следует создать локальный перехватчик Hibernate (присоединенный к открытому сеансу) вместоглобальный перехватчик (присоединенный к SessionFactory), а затем настройте его сеанс

AuditableInterceptor interceptor = new AuditableInterceptor()
Session session = sessionFactory.openSession(interceptor);

/**
  * do it before processing anything if you use local interceptor
  */ 
interceptor.setSession(session);

О триггерах, это зависит от других вопросов, таких как администрирование БД (у вас есть доступ к администрированию БД. Если нет, обратитесь к БДВаша лучшая ставка).

...