Вставка смешанного суррогатного композитного ключа в JPA 2.0, PostgreSQL и Hibernate 3.5 - PullRequest
2 голосов
/ 01 мая 2010

Прежде всего, мы используем JPA 2.0 и Hibernate 3.5 в качестве поставщика сохраняемости для базы данных PostgreSQL.

Мы успешно используем последовательность базы данных с помощью аннотаций JPA 2.0 в качестве автоматически сгенерированного значения для однополярных суррогатных ключей, и все работает нормально.

Теперь мы реализуем двухвременную схему базы данных, для которой требуется смешанный ключ следующим образом:

Table 1:
id             (pk, integer, auto-generated-sequence)
validTimeBegin (pk, dateTime)
validTimeEnd   (dateTime)
firstName      (varChar)

Теперь у нас проблема. Видите ли, если мы INSERT новый элемент, поле id генерируется автоматически, и это нормально. Только если мы хотим UPDATE поле в этой схеме, мы должны изменить столбец validTimeBegin БЕЗ изменения поля id и вставить его в виде новой строки, например:

ДО ОБНОВЛЕНИЯ РЯДА:

|---|-------------------------|-------------------------|-------------------|
| id|      validTimeBegin     |       validTimeEnd      |     firstName     |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:00:00.000 |                    NULL |            Gerald |
|---|-------------------------|-------------------------|-------------------|

ПОСЛЕ ОБНОВЛЕНИЯ РОУ, происходящего ровно в 2010-05-01-10: 35: 01.788 серверное время:

(we update the person with the id:1 to reflect his new first name...)
|---|-------------------------|-------------------------|-------------------|
| id|      validTimeBegin     |       validTimeEnd      |     firstName     |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:00:00.000 | 2010-05-01-10:35:01.788 |            Gerald |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:35:01.788 |                    NULL |             Jerry |
|---|-------------------------|-------------------------|-------------------|

Итак, наша проблема в том, что это вообще не работает с использованием автоматически сгенерированной последовательности для поля id, потому что при вставке новой строки идентификатор ВСЕГДА генерируется автоматически, хотя он действительно является частью составной ключ, который иногда должен вести себя по-другому.

Итак, мой вопрос: Есть ли способ сообщить hibernate через JPA, чтобы он прекратил автогенерацию поля id в случае, если я хочу создать новую разновидность того же человека и продолжаю работать как обычно в любом другом случае, или мне нужно взять на себя управление целое поколение id с пользовательским кодом?

Заранее спасибо, Джеральд

Ответы [ 2 ]

2 голосов
/ 12 ноября 2010

Итак ... Некоторое время прошло без каких-либо комментариев, и теперь я почти уверен, что это невозможно сделать. Фактически это одна из причин, почему разработчики начинают генерировать свои собственные уникальные ключи для баз данных через свои собственные id-генераторы на стороне приложения. Таким образом, база данных даже не знает о такой вещи, как суррогатный ключ; Он просто получает это.

Кстати: Мы решили нашу проблему, реализовав собственные методы для задачи обновления таких строк. Эти методы теперь зависят от OR-Mapper и никоим образом не совместимы с JPA 2.0, но JPA просто не поддерживает аннотации для такого поведения.

0 голосов
/ 04 мая 2010

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

  • Шаг 0: использовать идентификатор в качестве первичного ключа только в Hibernate. Используйте составной первичный ключ в Postgres.
  • Шаг 1. Добавьте в режим гибернации фильтры, которые автоматически фильтруют все строки с установленным validEndTime.
  • Шаг 2. Добавьте пользовательский оператор обновления в спящий режим, который вместо этого выполняет вставку.
  • Шаг 3: Добавить триггер в PostgreSQL, который автоматически устанавливает время окончания.
  • Шаг 4. Создайте ограниченный индекс для postgres для более быстрого поиска в hibernate.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...