Java Persistence API (JPA) и Hibernate предоставляют вам множество функций сопоставления, которые позволяют вам

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

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

Держите его простым и похожим

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

Не поймите меня неправильно. Я не говорю вам, что вы никогда не должны использовать сложные функции отображения. Иногда вам могут понадобиться иерархии наследования в вашей модели предметной области. Или вам может понадобиться добавить фрагменты SQL к вашим сопоставлениям, чтобы реализовать пользовательское преобразование. Но вы должны знать о недостатках таких сопоставлений:

  • Они создают накладные расходы, которые замедляют работу вашего приложения. Типичными примерами являются классы сущностей, которые наследуют некоторые из своих сопоставлений атрибутов, порядок ассоциаций по умолчанию и преобразование значений атрибутов. Эти сопоставления увеличивают сложность генерируемых операторов SQL.
  • Сложные сопоставления, основанные на редко используемых аннотациях, усложняют поддержку ваших классов сущностей.
  • Некоторые сопоставления вводят технические ограничения, о которых вы можете пожалеть позже. Примером этого является InheritanceType.SINGLE_TABLE сопоставление. Столбцы, отображаемые подклассами, содержат множество нулевых значений. Это предотвращает использование ограничений not null для обеспечения согласованности данных, а индексы часто игнорируются.

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

Определите, какие аннотации использовать

Простые аннотации сопоставления не требуют предоставления собственных фрагментов SQL и не скрывают структуру табличной модели. Часто используемые примеры:

  • @Entity и @Id для определения класса сущности и первичного ключа,
  • @Column если вы установите только атрибут имени,
  • @Temporal и @Enumerated для описания сопоставления конкретных типов и
  • @ManyToOne и @OneToOne аннотации к ассоциациям, управляемым моделью для объекта, который отображает столбец внешнего ключа.

Такие аннотации, как @ManyToMany, @AttributeConverter для использования пользовательских сопоставлений типов и @MappedSuperclass для использования очень простого сопоставления наследования, также можно использовать. Они вносят дополнительную сложность, но оказывают минимальное влияние на генерируемые операторы SQL.

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

  • Аннотация @Inheritance позволяет использовать наследование в модели предметной области. Модели реляционных таблиц не поддерживают эту концепцию и требуют сложных операций отображения.
  • Аннотации @Where и @OrderBy исключают элементы из ассоциации или определяют порядок ее элементов по умолчанию.

Просто быстрее

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