Краткая версия для поспешности:
В моей модели домена существуют разные таблицы/сущности, которые имеют одно и то же поле (UUID). Существует таблица, где мне нужно связать строки/экземпляры таких объектов с другими объектами, управляемыми JPA. Другими словами, экземпляр поля в этой таблице ссылок не будет известен заранее. Два подхода, о которых я могу думать, следующие:
- Используйте абстрактный объект и стратегию TABLE_PER_CLASS, или
- используйте
@MappedSuperClass
, чтобы сохранить имя класса экземпляра в таблице ссылок, или что-то подобное, что позволяет мне определять логику для получения фактического экземпляра из правой таблицы.
Оба имеют преимущества и недостатки с точки зрения сложности и производительности. Что вы считаете лучшим, может быть, третий вариант, или вы пробовали что-то подобное в прошлом и советовали бы/настоятельно предупреждали?
Длинная версия, если вы хотите больше фона:
У меня есть модель базы данных/объекта, в которой у многих типов есть общее поле: универсальный уникальный идентификатор (UUID). Причина этого в том, что экземпляры этих типов могут быть изменены. Изменения следуют за моделью команды, и их данные могут быть инкапсулированы и сами сохраняются. Позвольте называть такое изменение "мутацией". Должно быть возможно выяснить, какие мутации существуют в базе данных для любого данного объекта, и наоборот, на каком объекте действует сохраненная мутация.
Возьмите следующие объекты с UUID в качестве (чрезвычайно упрощенного) примера:
Чтобы сохранить "мутации", мы используем таблицу/объект, называемый MutationHolder
. Чтобы связать мутацию с ее целевой сущностью, там MutationEntityLink
. Единственная причина, по которой эти данные не относятся непосредственно к MutationHolder
, состоит в том, что могут быть прямые или косвенные ссылки, но это мало важно здесь, поэтому я ее не заметил:
Вопрос сводится к тому, как я могу моделировать поле entity
в MutationEntityLink
. Есть два подхода, о которых я могу думать.
Первый заключается в создании абстрактного @Entity
аннотированного класса с полем UUID. Customer
, Contract
и Address
расширят его. Таким образом, это стратегия TABLE_PER_CLASS. Я предполагаю, что я мог бы использовать это как тип для поля entity
, хотя я не уверен. Однако я опасаюсь, что это может привести к серьезному снижению производительности, поскольку JPA необходимо будет запросить многие таблицы, чтобы найти фактический экземпляр.
Во-вторых, просто используйте @MappedSuperClass
и просто сохраните UUID для объекта в поле entity
MutationEntityLink
. Чтобы получить фактическую сущность с этим UUID, мне пришлось бы ее решать программно. Добавление дополнительного столбца с именем класса объекта или другим, что позволяет мне идентифицировать его или вставить его в запрос JPQL. Это требует большей работы, но кажется более эффективным. Я не прочь кодировать некоторые классы утилиты или делать некоторые рефлексии/пользовательскую работу аннотации, если это необходимо.
Мой вопрос: какой из этих подходов кажется лучшим? Кроме того, у вас может быть лучшее предложение или заметить, что я что-то упускаю; например, может быть, есть способ добавить столбец типа, даже с наследованием TABLE_PER_CLASS, чтобы указать JPA на правую таблицу? Возможно, вы пробовали что-то подобное и хотите предупредить меня о многочисленных проблемах, которые возникнут.
Дополнительная информация:
- Мы создаем схему базы данных, поэтому мы можем добавлять все, что захотим.
- Одна стратегия наследования таблицы не является вариантом. Таблицы должны оставаться различными. По той же причине объединенное наследование также не подходит.
- Поставщик JPA - это Hibernate, и использование вещей, которые не являются частью стандарта JPA, не является проблемой.