Как провести ревизию отношений один-к-одному через спящий режим в двунаправленном режиме? - PullRequest
0 голосов
/ 03 апреля 2019

Я использую Hibernate Envers для аудита.

У меня есть два класса сущностей, A и B. Между ними существует взаимно-однозначное отношение. Таким образом, это создает две таблицы аудита A_aud и B_aud. Создание / Обновление для обоих осуществляется через один экран.

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

Как мне этого добиться?

И вот как я определил отображение с обеих сторон

    public class A implements Serializable {
           private B b;

           @OneToOne(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
           public B getB() {
             return b;
           }

           public void setB(B b) {
             this.b = b;
           }
}

public class B implements Serializable{
    private A a;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "A_ID", referencedColumnName = "id",nullable = false)
    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

1 Ответ

0 голосов
/ 09 апреля 2019

Всякий раз, когда два объекта связаны, например, в случае с вашим @OneToOne, изменения по обе стороны отношения не будут каскадно проверять другую сторону этого отношения, если только вы:

  1. Измените отношение, например, указав B на другой экземпляр A
  2. Изменить атрибут на другой стороне отношения

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

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

У вас есть несколько способов достичь желаемого:

  1. Использовать условный аудит
  2. Используйте атрибут, чтобы вызвать аудит.

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

Самый простой способ - это сделать (2). Чтобы это работало, вы должны добавить новое поле для обоих объектов, в котором будет храниться что-то, например, значение метки времени. Всякий раз, когда происходит изменение с любым объектом в вашем пользовательском интерфейсе, вы устанавливаете временную метку для обоих объектов, что фактически заставит Envers проверять оба объекта в одной транзакции, выполняя точно то, что вы хотите.

Это то, что пользователи часто упоминают, поэтому я создал HHH-13362 , где мы можем провести более подробное обсуждение того, как лучше всего разработать и улучшить это, не навязчивым способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...