Хранение исторических данных с помощью Java и Hibernate - PullRequest
5 голосов
/ 30 ноября 2010

Это проблема с обработкой исторических данных. Предположим, у вас есть класс MyClass, подобный следующему:

class MyClass {
    String field1;
    Integer field2;
    Long field3;

    getField1() {...}
    setField1(String ...) {...}

    ...
}

Теперь, предположим, что мне нужно, чтобы MyClass мог хранить и извлекать старые данные, как лучше всего это сделать?
требования должны также сохранять классы через Hibernate. И иметь не более двух таблиц на «сущность» : только одну таблицу или одну таблицу для класса «непрерывность» (ту, которая представляет сущность, которая развивается со временем) и другую таблицу для исторических данных (как предлагается здесь )
Обратите внимание, что я должен иметь возможность назначить произвольное допустимое время для значений полей.

Класс должен иметь интерфейс, подобный:

class MyClass {
    // how to store the fields????

    getField1At(Instant i) {...}
    setField1At(Instant i, String ...) {...}

    ...
}

В настоящее время я использую библиотеку JTemporal , и у нее есть класс TemporalAttribute<T>, похожий на карту: вы можете делать такие вещи, как T myAttr.get(Instant i), чтобы получить версию myAttr в Instant i , Я знаю, как сохранить TemporalAttribute в таблице с помощью Hibernate (это просто: я сохраняю SortedMap, используемый TemporalAttribute, и вы получаете таблицу с начальным и конечным допустимым временем и значением атрибута).
Реальная проблема в том, что здесь у нас есть несколько атрибутов.
У меня есть решение, но оно не ясное, и я хотел бы услышать ваши идеи.

Ответы [ 2 ]

5 голосов
/ 30 ноября 2010

Ваш проект напоминает мне о Hibernate Envers .

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

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

Использование Hibernate Envers для этого разъединяет сущности и данные ревизий (в базе данных и в вашем коде).

0 голосов
/ 30 ноября 2010

Вы можете сделать что-то подобное, просто добавив номер версии в свой класс домена. Я сделал что-то вроде этого, где Id был составной между назначенным номером в БД и номером версии, но я бы посоветовал против этого. Используйте обычный суррогатный ключ, и если вы действительно хотите, сделайте кортеж [id, version] естественным ключом.

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

Вы должны написать множество сервисных тестов для обеспечения целостности кода, который управляет версией.

...