Как лучше всего моделировать наследование в объектах JPA - PullRequest
3 голосов
/ 14 января 2020

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

Предположим, мы иметь базу данных сотрудников, как в примере Oracle HR . Теперь эта база данных не совсем реалистична c. Зарплаты обычно меняются со временем, и мы будем следить за тем, как менялись зарплаты. Например, в трудовом договоре может быть сказано, что каждый год в декабре сотрудники встречаются со своим менеджером, чтобы обсудить зарплату на следующий год.

Поэтому мы удалили бы поле зарплаты из HR.EMPLOYEES и создали новую таблицу HR .SALARIES:

EMPLOYEE_ID NOT NULL NUMBER(6)
VALID_FROM NOT NULL DATE
SALARY NUMBER(8,2)

Первичный ключ будет состоять из EMPLOYEE_ID и VALID_FROM.

Итак, теперь, если Пэт встретится со своим менеджером Майклом в декабре и договорится о новой зарплате, мы добавим новую запись в HR.SALARIES.

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

В конце года компания проверяется. Аудитор задается вопросом, почему чек на оплату, выданный Пэт в январе, не соответствует записи о зарплате в базе данных. Чтобы убедиться, что аудиторы всегда могут понять, почему система приняла определенные решения (например, выдать чек на определенную сумму), нам необходимо сохранить историю изменений.

Изменить HR.SALARIES на:

EMPLOYEE_ID NOT NULL NUMBER(6)
VALID_FROM NOT NULL DATE
SALARY NUMBER(8,2)
CHANGE_DATE NOT NULL DATE

Добавить новую таблицу HR.SALARIES_CHANGE_HISTORY:

EMPLOYEE_ID NOT NULL NUMBER(6)
VALID_FROM NOT NULL DATE
SALARY NUMBER(8,2)
CHANGE_DATE NOT NULL DATE

Первичный ключ будет состоять из EMPLOYEE_ID, VALID_FROM и CHANGE_DATE.

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

Теперь мы наконец подходим к моему вопросу. Как лучше всего моделировать эту БД в JPA, и можем ли мы каким-то образом воспользоваться преимуществами наследования, поскольку таблицы HR.SALARIES и HR.SALARIES_CHANGE_HISTORY идентичны, за исключением того факта, что CHANGE_DATE является частью первичного ключа в HR.SALARIES_CHANGE_HISTORY.

В JavaEE существует @MappedSuperclass, который поначалу звучит хорошо, но невозможно использовать разные первичные ключи в иерархии классов, которая использует @MappedSupperclass (см. JSR-000338 JavaTM Persistence 2.1, раздел 2.4 и JSR 220: Enterprise JavaBeansTM, версия 3.0, раздел 2.1.4 ).

Есть ли способ избежать дублирования кода в компонентах для SALARIES и SALARIES_CHANGE_HISTORY?

...