Envers: однонаправленный OneToMany без дополнительной таблицы аудита?

Следующая схема базы данных:

Сотрудник [EMP_ID (PK), имя, зарплата]

Телефон [ID (PK), number_str, OWNER_ID (FK)]

Employee_aud [EMP_ID (PK), REV (PK / FK), REVTYPE, имя, зарплата]

Phone_aud [ID (PK), REV (PK / FK), REVTYPE, number_str]

Employe_phone_aud [REV (PK / FK), OWNER_ID (PK / FK), REVTYPE (PK / FK)]

может быть выражено следующими объектами Java:

Сотрудник:

@Entity
@Audited
public class Employee {

    @Id
    @GeneratedValue
    @Column(name = "EMP_ID")
    private long id;

    @Column
    private String name;

    @Column
    private int salary;

    @OneToMany
    @JoinColumn(name = "OWNER_ID", referencedColumnName = "EMP_ID")
    private final List<Phone> phones = new ArrayList<Phone>();

    public Employee(final String name, final int salary) {
        this.name = name;
        this.salary = salary;
    }

    public long getId() {
        return id;
    }

    public void setId(final long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(final int salary) {
        this.salary = salary;
    }

    public void addPhone(final Phone phone) {
        this.phones.add(phone);
    }
}

Телефон:

@Entity
@Audited
public class Phone {

    @Id
    @GeneratedValue
    private long id;

    @Column(name = "number_str")
    private String number;

    public Phone(final String number) {
        this.number = number;
    }

    public long getId() {
        return id;
    }

    public void setId(final long id) {
        this.id = id;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(final String number) {
        this.number = number;
    }
}

Как видите, существует связующая таблица между таблицами аудита, но нет связывающей таблицы между таблицами сущностей. В руководстве разработчика Hibernate-Envers я нашел следующий текст:

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

Это моя интерпретация этого текста: «Мой сотрудник может принадлежать множеству телефонных сущностей». Если я, например, добавлю телефон определенному сотруднику, мой сотрудник будет изменен, и, следовательно, необходимо будет сделать запись аудита. Используя приведенное выше сопоставление, это приведет к записи аудита для объекта "Телефон", а не для сотрудника. Эта проблема решается с помощью таблицы связывания (поскольку в этой таблице описаны изменения в коллекции телефонов, принадлежащей сотруднику).

Теперь мои 3 вопроса: - Правильно ли я понимаю вышеприведенное утверждение или мне не хватает чего-то особенного? - Если бы Envers не создавал эту таблицу связывания, можно было бы также отслеживать эти отношения, просматривая таблицу phone_aud. Это правда? - Можно ли настроить / расширить envers для поддержки такого поведения?

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

Спасибо!


person Andreas Aumayr    schedule 05.11.2013    source источник


Ответы (2)


  1. да, вы правильно поняли утверждение из документации
  2. да, но чтение истории изменений «Телефон» даст вам последующие идентичные объекты (так как изменится только emp_id)
  3. нет, в настоящее время изменить это поведение невозможно. Если вы, например, измените отображение на двунаправленное отношение "один ко многим"
person adamw    schedule 06.11.2013
comment
Спасибо за ваш комментарий! Действительно - ›Я перепробовал почти все возможные сопоставления (как однонаправленные, так и двунаправленные) и пришел к одному и тому же решению. Рад слышать, что ничего важного не пропустил. - person Andreas Aumayr; 07.11.2013
comment
Вы исправили это? Потому что ищу решение той же проблемы. - person AppSensei; 23.03.2015
comment
Мне не пришлось его исправлять, поскольку это был всего лишь небольшой прототип, чтобы познакомиться с фреймворком. Адам уже более точно сформулировал проблему и дал подсказку к решению: если бы я прочитал историю Phone, у меня было бы несколько объектов, которые различаются только на стороне базы данных. Сущности Java остаются без изменений. Решение зависит от ваших потребностей: если вы хотите избежать таблицы связывания аудита всеми способами, вы должны сделать отношения двунаправленными. Если двунаправленная связь невозможна, вам придется жить с дополнительной таблицей (по крайней мере, в схеме аудита). Надеюсь, это поможет. - person Andreas Aumayr; 29.03.2015

Сегодня это возможно с аннотацией @AuditJoinTable, это очень старая функция

person László Tóth    schedule 09.07.2020