Hibernate Envers: аудит с помощью встроенного класса в составном ключе - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь активировать аудит для объекта JPA с помощью Hibernate Envers (текущая версия: 5.4.1.Final).

Проблема: У объекта есть составной ключ (@EmbeddedId) и класс ключа имеет сам класс @Embedded.Я не получаю @Audit на работу.

Вопрос: В чем причина проблемы, и можете ли вы предложить решение / обходной путь?

Пример: База данных использует концепцию общего пространства данных для всех таблиц.Таблица item может иметь столбцы: dataspace1, dataspace2, dataspace3, itemid, value1, value2, ....Конечно, таблица аудита item_aud присутствует, как и ожидалось Hibernate Envers.

У меня есть следующие классы:

@Entity
@Table(name = "item")
@Audited
public class Item {
    @EmbeddedId 
    private ItemKey itemKey;

    @Column(name = "value1")
    private String value1;

    @Column(name = "value2")
    private String value2;
    ...
}    

@Embeddable
public class ItemKey {
    @Embedded 
    private DataSpace dataSpace;

    @Column(name = "itemid")
    private String itemId;
}

@Embeddable
public class DataSpace {
    @Column(name = "dataspace1")
    private String dataSpace1;

    @Column(name = "dataspace2")
    private String dataSpace2;

    @Column(name = "dataspace3")
    private String dataSpace3;
}

При этой установке я получаю исключение: org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType

Сохранение / загрузка объектов работает нормально, когда @Audit деактивировано.Это также работает, когда я помещаю три свойства DataSpace в ItemKey.Тем не менее, мы бы предпочли решение с отдельным классом DataSpace, так как оно используется другими организациями.

1 Ответ

0 голосов
/ 28 февраля 2019

Учитывая ваши комментарии, это похоже на ошибку.

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

Хотя в спецификации JPA явно не указано, что расширение класса Embeddable должно поддерживаться, Hibernate поддерживает эту конструкцию.

Вы также должны иметь возможность сохранить get/ set методы, поэтому не нужно менять код клиента.

@MappedSuperclass
@Embeddable
public class DataSpace {
    @Column(name = "dataspace1")
    private String dataSpace1;

    @Column(name = "dataspace2")
    private String dataSpace2;

    @Column(name = "dataspace3")
    private String dataSpace3;
}

@Embeddable
public class ItemKey extends DataSpace {

    @Column(name = "itemkey")
    private String itemKey;

    public void setDataSpace(DataSpace dataSpace){
        //copy to the inherited fields
    }

    public DataSpace getDataSpace(){
        DataSpace dataSpace = new DataSpace();
        //populate form the inherited fields

        return dataSpace;
    }
}
...