Hibernate Tips Book-Auszug: So ordnen Sie eine Vererbungshierarchie einer Tabelle zu

1. Einführung

Vererbung ist eines der Schlüsselkonzepte in Java. Daher überrascht es nicht, dass die meisten Domain-Modelle es verwenden. Leider ist dieses Konzept in relationalen Datenbanken nicht vorhanden, und Sie müssen einen Weg finden, die Vererbungshierarchie einem relationalen Tabellenmodell zuzuordnen.

JPA und Hibernate unterstützen unterschiedliche Strategien, bei denen die Vererbungshierarchie verschiedenen Tabellenmodellen zugeordnet wird. Werfen wir einen Blick auf ein Kapitel meines neuen Buches https://www.amazon.com/Hibernate-Tips-solutions-common-problems-ebook/dp/B06XXGYZHS/in dem ich die SingleTable -Strategie erkläre. Es ordnet alle Klassen der Vererbungshierarchie derselben Datenbanktabelle zu.

Ich erkläre die anderen Vererbungs-Mapping-Strategien von Hibernate in meinem Hibernate Tips Book . Es ist ein Kochbuch mit mehr als 70 gebrauchsfertigen Rezepten für Themen wie grundlegende und erweiterte Mappings, Protokollierung, Java 8-Unterstützung, Caching und statisch und dynamisch definierte Abfragen. Sie können https://www.amazon.com/Hibernate-Tips-solutions-common-problems-ebook/dp/B06XXGYZHS/diese Woche bei Amazon zu einem Sonderpreis von nur 2,99 $ erwerben.


2. Tipps zum Ruhezustand - So ordnen Sie eine Vererbungshierarchie einer Tabelle zu

2.1. Problem

Meine Datenbank enthält eine Tabelle, die ich einer Vererbungshierarchie von Entitäten zuordnen möchte. Wie definiere ich eine solche Zuordnung?

2.2. Lösung

JPA und Hibernate unterstützen unterschiedliche Vererbungsstrategien, mit denen Sie die Entitäten unterschiedlichen Tabellenstrukturen zuordnen können. Die SingleTable -Strategie ist eine davon und ordnet eine Vererbungshierarchie von Entitäten einer einzelnen Datenbanktabelle zu.

Schauen wir uns das Entitätsmodell an, bevor ich die Details der SingleTable -Strategie erkläre. Authors kann verschiedene Arten von Publications schreiben, wie Books und BlogPosts . Die Publication -Klasse ist die Superklasse der Book - und BlogPost -Klassen.

Die Strategie SingleTable ordnet die drei Entitäten der Vererbungshierarchie der Tabelle publication zu.

Wenn Sie diese Vererbungsstrategie verwenden möchten, müssen Sie die Superklasse mit einer Annotation @ Inheritance annotieren und InheritanceType.SINGLE TABLE als Wert des Attributs strategy__ angeben.

Sie können die Superklasse auch mit einer @ DiscriminatorColumn -Annotation versehen, um den Namen des Diskriminatorwerts zu definieren. Hibernate verwendet diesen Wert, um die Entität zu bestimmen, der ein Datenbanksatz zugeordnet werden muss. Wenn Sie keine Diskriminatorspalte definieren, verwenden Hibernate und alle anderen JPA-Implementierungen die Spalte 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 Set<Author> authors = new HashSet<Author>();

    ...
}

Die Unterklassen müssen die Superklasse erweitern, und Sie müssen sie mit einer @ Entity -Annotation versehen.

Die JPA-Spezifikation empfiehlt außerdem, sie mit einer Annotation @ DiscriminatorValue zu kommentieren, um den Diskriminatorwert für diese Entitätsklasse zu definieren. Wenn Sie diese Anmerkung nicht angeben, generiert Ihre JPA-Implementierung einen Diskriminatorwert.

Die JPA-Spezifikation definiert jedoch nicht, wie der Diskriminatorwert generiert wird, und Ihre Anwendung ist möglicherweise nicht für andere JPA-Implementierungen portierbar. Der Ruhezustand verwendet den einfachen Entitätsnamen als Diskriminator.

@Entity
@DiscriminatorValue("Book")
public class Book extends Publication {

    private int numPages;

    ...
}

Die Strategie SingleTable erfordert nicht, dass Hibernate komplexe Abfragen generiert, wenn Sie eine bestimmte Entität auswählen, eine polymorphe Abfrage ausführen oder eine polymorphe Zuordnung durchlaufen möchten.

Author a = em.find(Author.class, 1L);
List<Publication> publications = a.getPublications();

Alle Entitäten werden in derselben Tabelle gespeichert und Hibernate kann sie ohne zusätzliche JOIN -Klausel auswählen.

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. Quellcode

Einen Downloadlink für ein Projekt mit ausführbaren Testfällen für diesen Hibernate-Tipp finden Sie im book .

2.4. Lern mehr

Sie können die Entitäten der Vererbungshierarchie auch mehreren Datenbanktabellen zuordnen. Wie das geht, zeige ich Ihnen im Kapitel Wie eine Vererbungshierarchie mehreren Tabellen zugeordnet wird .

3. Zusammenfassung

Wie Sie in diesem Hibernate-Tipp gesehen haben, bieten JPA und Hibernate eine einfache Möglichkeit, eine Vererbungshierarchie einer einzelnen Datenbanktabelle zuzuordnen.

Sie müssen nur die Superklasse mit @ Inheritance (Strategie = InheritanceType.SINGLE TABLE) kommentieren, und Sie sollten auch die Unterklassen mit @ DiscriminatorValue ("Book") __ kommentieren.