JPA: реализация иерархии моделей - @MappedSuperclass и @Inheritance - PullRequest
56 голосов
/ 12 марта 2012

Я использую Play Framework 1.2.4 с PostgreSQL и JPA.Я хотел бы иметь иерархию модели и увидеть, что есть несколько альтернатив для этого.

У меня есть базовый класс (абстрактный) и два конкретных класса, расширяющих этот базовый класс.Я не хочу сохранять этот базовый класс, пока я хочу иметь конкретные классы.В базовом классе у меня есть другие классы Model в качестве свойств, другими словами, у меня есть @ManyToOne отношения в моем базовом классе.

Мой вопрос: каков наилучший способ реализации этого?Используете @MappedSuperclass или @Inheritance со стратегией TABLE_PER_CLASS?Я немного сбит с толку, поскольку они кажутся фактически эквивалентными.

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

Ответы [ 2 ]

119 голосов
/ 12 марта 2012

MappedSuperClass должен использоваться для наследования свойств, ассоциаций и методов.

Наследование сущностей должно использоваться, когда у вас есть сущность и несколько дочерних сущностей.

Вы можете сказать, нужна ли вам одна или другая, отвечая на эти вопросы: есть ли какая-то другая сущность вмодель, которая может иметь связь с базовым классом?

Если да, то базовый класс на самом деле является сущностью, и вам следует использовать наследование сущностей.Если нет, то базовый класс на самом деле является классом, который содержит атрибуты и методы, общие для нескольких несвязанных сущностей, и вам следует использовать сопоставленный суперкласс.

Например:

  • Вы можете иметь несколько видов сообщений: SMS-сообщения, сообщения электронной почты или телефонные сообщения.И у человека есть список сообщений.Вы также можете иметь напоминание, связанное с сообщением, независимо от типа сообщения.В этом случае Message явно является сущностью, и необходимо использовать наследование сущности.
  • Все ваши доменные объекты могут иметь дату создания, дату изменения и идентификатор, и вы можете сделать так, чтобы они наследовали от базового класса AbstractDomainObject.,Но ни одна сущность никогда не будет иметь ассоциацию с AbstractDomainObject.Это всегда будет ассоциация с более конкретной организацией: клиент, компания, что угодно.В этом случае имеет смысл использовать MappedSuperClass.
13 голосов
/ 09 ноября 2017

Как я объяснил в этой статье , @MappedSupperclass отличается от аннотации @Inheritance.

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

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

Аннотация @Inheritance предназначена для материализации модели наследования ООП в структуре таблицы базы данных. Более того, вы можете запросить базовый класс, аннотированный @Inheritance, но вы не можете сделать это для базового класса, аннотированного @MappedSuperclass.

Теперь причина, по которой вы хотите использовать аннотацию JPA @Inheritance, заключается в реализации шаблонов, основанных на поведении, таких как шаблон стратегии .

С другой стороны, @MappedSuperclass - это просто способ многократного использования как базовых свойств, ассоциаций, так и даже сущности @Id с использованием общего базового класса. Тем не менее, вы можете достичь почти той же цели, используя тип @Embeddable. Единственное существенное отличие состоит в том, что вы не можете повторно использовать определение @Id с @Embeddable, но вы можете сделать это с @MappedSuperclass.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...