Как Envers справляется с изменениями схемы?

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

Каков ваш опыт работы с Envers в этом отношении? Как вы обрабатываете изменения схемы и существующие данные с помощью Envers?

Обновление 1:

Это не просто добавление удаления простых столбцов из таблицы, но, например, при изменении простого отношения Forein-Key в отдельный объект с двумя 1: n-отношениями (M2M с атрибутными столбцами. Это "логическое" изменение в вашей модели данных. Как вы справляетесь с этим при использовании Envers, когда это уже историзированные данные в соответствии со старой моделью? Есть ли альтернатива ручному написанию sql-скриптов и перенос их в новое представление?

Ответ 1

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

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

Ответ 2

Не должно быть проблем с модификацией существующей схемы, так как Envers полагается на @Entities для создания таблиц аудита. Поэтому, если вы добавляете или удаляете столбец из существующей таблицы, пока это изменение отражается в вашем @Entity/@Audited JavaBean, оно должно быть в порядке.

Ответ 3

Рефакторинг внешнего ключа должен быть в порядке с Envers. Поскольку Envers создает таблицу соединений даже для отношений "один ко многим", она должна быть прямой, чтобы изменить ее, чтобы стать отношениями "многие ко многим". Я извлек один абзац из официального документа :

9,3. @OneToMany + @JoinColumn

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

Чтобы иметь возможность указать дополнительную таблицу соединений, существует специальная аннотация: @AuditJoinTable, которая имеет аналогичную семантику для JPA @JoinTable.

Одним из особых случаев являются отношения, сопоставленные с @OneToMany + @JoinColumn on с одной стороны, и @ManyToOne + @JoinColumn (insertable = false, updatable = false) со стороны. Такие отношения на самом деле двунаправленная, но владеющая сторона - это сборник (см. здесь здесь).

Чтобы правильно проверить такие отношения с Envers, вы можете использовать @AuditMappedBy аннотация. Он позволяет указать обратное свойство (используя элемент mappedBy). В случае индексированных коллекций, индексный столбец также должен отображаться в ссылочном объекте (используя @Column (insertable = false, updatable = false) и указывается с помощью positionMappedBy. Эта аннотация повлияет только на то, как Envers работает. Обратите внимание, что аннотация экспериментальна и может меняться в будущем.