Реализация решения для истории данных / управления версиями для приложения на основе Hibernate (с изюминкой) - PullRequest
6 голосов
/ 22 декабря 2009

Сначала основные факты: веб-приложение Java, Spring, Hibernate, MySQL.

Ситуация такова, что у меня есть сложная объектная модель, например, Автомобиль . Это состоит из множества объектов (Engine, Tyres, ...) с отношениями «многие к одному» и «один ко многим» между ними.

Сейчас существует много автомобилей, и время от времени кто-то осматривает автомобиль и создает Отчет о проверке. Отчет относится ко многим частям автомобиля, отображает их свойства и т. Д.

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

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

Я смотрел на « Медленно меняющиеся размеры », и кажется, что управление версиями автомобиля и его частей может быть выполнено с использованием подхода типа 6.

То, что мне трудно понять (возможно, из-за моего ограниченного опыта Hibernate), заключается в следующем:

Как собрать экземпляры отчетов в Hibernate, чтобы они ссылались на правильные версии каждой части автомобиля? В отчетах указана дата, и в каждой версии деталей автомобиля будут диапазоны дат они были действительны, поэтому я думаю, что я мог бы сделать это с некоторым сложным HQL / SQL. Но есть ли более простой и автоматический способ сделать это с помощью Hibernate?

Ответы [ 3 ]

6 голосов
/ 22 декабря 2009

Вы можете взглянуть на JBoss envers для управления версиями ваших объектов. Я не уверен, что он подходит для вашего случая использования, но посмотрите.

1 голос
/ 22 декабря 2009

Я использовал предложенный вами подход (Тип 6) с Hibernate, и он работал нормально для меня. Запросы для отчетов стали немного сложнее, но не намного, так как для всех запросов требовалось одно и то же предложение (например, 'и: reportTime> = x.startTime и (: reportTime

Я создал интерфейс и базовый класс (интерфейс был необходим только для временных подклассов, родительские элементы которых не были временными) для объектов, которые поддерживали этот подход с двумя свойствами (например, startTime и endTime) и базовым классом для DAO, работающих с временные объекты, которые имели некоторую функциональность, часто необходимы. Вещи, которые я положил в эту базу DAO:

  1. Предотвращение изменений в экземплярах, для которых прошло время начала (кроме установки времени окончания в будущем)
  2. Автоматическое закрытие (т.е. заполнение endTime) предыдущего экземпляра, если был добавлен новый экземпляр (например, oldInstance.endTime = newInstance.startTime)
  3. Добавление стандартного предложения для выбора текущих объектов во время запроса к запросам HQL.
  4. Работа с дубликатами, если по какой-то причине в текущий момент времени были найдены два действительных экземпляра / версии (я упорядочил свои запросы по 'startTime desc' и взял только первый возвращенный)

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

1 голос
/ 22 декабря 2009

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

...