В процессе работы с данными нередко требуется, помимо всего прочего, сохранять историю манипуляций с ними. Существует несколько способов это сделать.
- Реализация в слое бизнес-логики
В этом случае в бизнес-логике приложения появляется довольно много «сквозного» функционала, который, чтобы не нарушать принцип DRY, приходится заворачивать в АОП или применять другие не самые простые решения. - Использование триггеров
В этом случае функционал отслеживания изменений полностью исключается из приложения, но вместо этого разработчик получает как минимум зависимость от конкретной СУБД. - Использование специализированных решений
Специальные библиотеки или их наборы, которые существенно облегчают решение подобных задач в прикладном ПО или решают их полностью автоматически.
Hibernate Envers это дополнительный компонент всем известной библиотеки Hibernate, который призван реализовать отслеживание изменений данных в автоматическом режиме. Hibernate Envers действительно автоматизирует всё. И создание таблиц для хранения истории изменений и сам процесс отслеживания и сохранения новых версий данных.
Так как это всё-таки дополнительный компонент, он не входит в стандартную поставку Hibernate и даже Spring Boot Starter Data JPA. Поэтому его нужно подключить к проекту, например с помощью Maven.
1 2 |
org.hibernate hibernate-envers |
Hibernate Envers добавляет две аннотации. @Audited и @NotAudited.
Аннотация @Audited обозначает поля таблицы (класса сущности), изменения в которых необходимо отслеживать. Если необходимо отслеживать все поля, то данной аннотацией можно отметить сразу весь класс сущности, как это показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Entity @AllArgsConstructor @NoArgsConstructor @Data @Audited public class Goods { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; @Column private String description; } |
Аннотация @NotAudited обозначает поля, которые необходимо исключить из отслеживания (это особенно актуально, если аннотацией @Audited отмечен весь класс).
После того, как вышеуказанные аннотации расставлены нужным образом при запуске приложения Hibernate создаёт дополнительные таблицы для отслеживания истории.
Первая таблица называется revinfo и содержит номер версии и отметку о времени её создания (timestamp).
Вторая таблица называется, также как и отслеживаемая сущность, но с суффиксом «_aud». Данная таблица содержит все поля отслеживаемой сущности, для которых при помощи рассмотренных выше аннотаций включено сохранение истории, а также специальные поля для связи с таблицей revinfo и цифровой код обозначающий действие, которое было совершено с записью.
Для наглядности приведём пример содержимого таблицы goods_aud, в которой сохраняется история изменений для сущности, которую мы рассматривали в примере кода.
Поле id здесь не уникально, т.к. обозначает id записи в основной таблице, для которой сохранена запись в истории. Поле rev это номер версии для таблицы revinfo. А, числовое значение в поле revtype обозначает то, действие, которое выполнялось с записью (0- создание новой записи, 1 – редактирование существующей записи, 2 – удаление существующей записи).
Также для наглядности ознакомимся с содержимым таблицы revinfo.
Поле rev это номер версии, который нам знаком из предыдущей таблицы, а revtstmp это отметка времени внесения изменений в формате UNIX timestamp.
Hibernate Envers может отслеживать изменения для произвольного количества сущностей. В это случае в базе данных будет соответствующее количество таблиц с историей (по одной для каждой сущности).
Добавить комментарий