Отслеживание изменения данных в таблицах базы данных с помощью Hibernate Envers

В процессе работы с данными нередко требуется, помимо всего прочего, сохранять историю манипуляций с ними. Существует несколько способов это сделать.

  • Реализация в слое бизнес-логики
    В этом случае в бизнес-логике приложения появляется довольно много «сквозного» функционала, который, чтобы не нарушать принцип DRY, приходится заворачивать в АОП или применять другие не самые простые решения.
  • Использование триггеров
    В этом случае функционал отслеживания изменений полностью исключается из приложения, но вместо этого разработчик получает как минимум зависимость от конкретной СУБД.
  • Использование специализированных решений
    Специальные библиотеки или их наборы, которые существенно облегчают решение подобных задач в прикладном ПО или решают их полностью автоматически.

Hibernate Envers это дополнительный компонент всем известной библиотеки Hibernate, который призван реализовать отслеживание изменений данных в автоматическом режиме. Hibernate Envers действительно автоматизирует всё. И создание таблиц для хранения истории изменений и сам процесс отслеживания и сохранения новых версий данных.

Так как это всё-таки дополнительный компонент, он не входит в стандартную поставку Hibernate и даже Spring Boot Starter Data JPA. Поэтому его нужно подключить к проекту, например с помощью Maven.

Hibernate Envers добавляет две аннотации. @Audited и @NotAudited.

Аннотация @Audited обозначает поля таблицы (класса сущности), изменения в которых необходимо отслеживать. Если необходимо отслеживать все поля, то данной аннотацией можно отметить сразу весь класс сущности, как это показано ниже:

Аннотация @NotAudited обозначает поля, которые необходимо исключить из отслеживания (это особенно актуально, если аннотацией @Audited отмечен весь класс).

После того, как вышеуказанные аннотации расставлены нужным образом при запуске приложения Hibernate создаёт дополнительные таблицы для отслеживания истории.

Первая таблица называется revinfo и содержит номер версии и отметку о времени её создания (timestamp).

Вторая таблица называется, также как и отслеживаемая сущность, но с суффиксом «_aud». Данная таблица содержит все поля отслеживаемой сущности, для которых при помощи рассмотренных выше аннотаций включено сохранение истории, а также специальные поля для связи с таблицей revinfo и цифровой код обозначающий действие, которое было совершено с записью.

Для наглядности приведём пример содержимого таблицы goods_aud, в которой сохраняется история изменений для сущности, которую мы рассматривали в примере кода.

Поле id здесь не уникально, т.к. обозначает id записи в основной таблице, для которой сохранена запись в истории. Поле rev это номер версии для таблицы revinfo. А, числовое значение в поле revtype обозначает то, действие, которое выполнялось с записью (0- создание новой записи, 1 – редактирование существующей записи, 2 – удаление существующей записи).

Также для наглядности ознакомимся с содержимым таблицы revinfo.

Список версий

Поле rev это номер версии, который нам знаком из предыдущей таблицы, а revtstmp это отметка времени внесения изменений в формате UNIX timestamp.

Hibernate Envers может отслеживать изменения для произвольного количества сущностей. В это случае в базе данных будет соответствующее количество таблиц с историей (по одной для каждой сущности).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *