Автор оригинала: thorben.janssen.
1. Введение
Наследование является одним из ключевых понятий в Java. Таким образом, это не удивительно, что большинство моделей домена использовать его. Но, к сожалению, эта концепция не существует в реляционных базах данных, и вам нужно найти способ сопоставить иерархию наследования с реляционной моделью таблицы.
JPA и Hibernate поддерживают различные стратегии, которые навечают иерархию наследования с различными моделями таблиц. Давайте посмотрим на главу моей новой книги Hibernate Советы – Более 70 решений общих проблем Hibernate в котором я объясню Одноместный стратегия. Он отображает все классы иерархии наследования в одной таблице базы данных.
Я объясняю другие стратегии отображения наследования Hibernate в моем Спящий Советы книга . Это поваренная книга с более чем 70 готовыми к использованию рецептами для таких тем, как основные и продвинутые карты, журналирование, поддержка Java 8, кэширование и статически и динамически определенные запросы. Вы можете получить его на этой неделе на Amazon по специальной стартовой цене всего $ 2,99.
2. Советы по спячке – Как сопоставить иерархию наследования с одной таблицей
2.1. Проблема
Моя база данных содержит одну таблицу, которую я хочу сопоставить с иерархией наследования сущностей. Как определить такое отображение?
2.2. Решение
JPA и Hibernate поддерживают различные стратегии наследования, которые позволяют сопоставить объекты с различными структурами таблиц. Одноместный стратегия является одним из них и отображает иерархию наследования сущностей в единую таблицу баз данных.
Давайте посмотрим на модель сущности, прежде чем я объясню детали Одноместный стратегия. Авторы может писать различные виды Публикации , как Книжные и BlogPosts . Публикация класс является супер классом Книжный и БлогПост Классы.
Одноместный стратегия отображает три сущности иерархии наследования к публикация стол.
Если вы хотите использовать эту стратегию наследования, вам нужно аннотировать суперкласс @Inheritance аннотация и обеспечить InheritanceType.SINGLE_TABLE как ценность стратегический атрибут.
Вы также можете аннотировать суперкласс с @DiscriminatorColumn аннотация для определения имени значения дискриминатора. Hibernate использует это значение для определения сущности, к которой он должен сопоставить запись базы данных. Если вы не определяете столбец дискриминации, как я делаю в следующем фрагменте кода, Hibernate и все другие реализации JPA используют столбец DTYPE .
@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Publication { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", updatable = false, nullable = false) private Long id; @Version private int version; private String title; private LocalDate publishingDate; @ManyToMany @JoinTable( name="PublicationAuthor", joinColumns={@JoinColumn(name="publicationId", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")}) private Setauthors = new HashSet (); ... }
Подклассы должны расширить суперкласс, и вы должны аннотировать их с @Entity аннотация.
Спецификация JPA также рекомендует аннотировать его @DiscriminatorValue аннотация для определения значения дискриминатора для этого класса сущности. Если вы не предоставите эту аннотацию, реализация JPA генерирует распознавание значений.
Но спецификация JPA не определяет, как создать значение дискриминатора, и ваше приложение не может быть портативным для других реализаций JPA. Hibernate использует простое имя сущности в качестве дискриминационных.
@Entity @DiscriminatorValue("Book") public class Book extends Publication { private int numPages; ... }
Одноместный Стратегия не требует hibernate для генерации каких-либо сложных запросов, если вы хотите выбрать конкретную сущность, выполнить полиморфный запрос или пройти полиморфную ассоциацию.
Author a = em.find(Author.class, 1L); Listpublications = a.getPublications();
Все объекты хранятся в одной таблице, и Hibernate может выбрать их оттуда без дополнительного ПРИСОЕДИНИТЬСЯ статья.
15:41:28,379 DEBUG [org.hibernate.SQL] - select author0_.id as id1_0_0_, author0_.firstName as firstNam2_0_0_, author0_.lastName as lastName3_0_0_, author0_.version as version4_0_0_ from Author author0_ where author0_.id=? 15:41:28,384 DEBUG [org.hibernate.SQL] - select publicatio0_.authorId as authorId2_2_0_, publicatio0_.publicationId as publicat1_2_0_, publicatio1_.id as id2_1_1_, publicatio1_.publishingDate as publishi3_1_1_, publicatio1_.title as title4_1_1_, publicatio1_.version as version5_1_1_, publicatio1_.numPages as numPages6_1_1_, publicatio1_.url as url7_1_1_, publicatio1_.DTYPE as DTYPE1_1_1_ from PublicationAuthor publicatio0_ inner join Publication publicatio1_ on publicatio0_.publicationId=publicatio1_.id where publicatio0_.authorId=?
2.3. Исходный код
Вы можете найти ссылку на загрузку для проекта с высовываемыми тестовыми случаями для этого наконечника Hibernate в книжный .
2.4. Узнайте больше
Можно также сопоставить сущности иерархии наследования с несколькими таблицами баз данных.
Я покажу вам, как это сделать в главе Как сопоставить иерархию наследования с несколькими таблицами
.
3. Резюме
Как вы видели в этом Совете Hibernate, JPA и Hibernate предоставляют простой вариант для карты иерархии наследования в единую таблицу баз данных. Вы просто должны аннотировать суперкласс с @Inheritance (стратегия. SINGLE_TABLE) и вы также должны аннотировать подклассы с @DiscriminatorValue (“Книга”) .
Вы можете получить больше рецептов, как это в моей новой книге Советы hibernate: Более 70 решений общих проблем Hibernate . Это дает вам более 70 готовых к использованию рецептов для таких тем, как основные и продвинутые карты, журналирование, поддержка Java 8, кэширование и статически и динамически определенные запросы. Всего за несколько дней, вы можете получить электронную книгу за $ 2,99 и мягкой обложке за $ 12,99 на Amazon .