5.1 Beschreibung

Und schließlich ist die letzte Strategie Tabelle pro Klasse. Das bedeutet, dass für jede Klasse eine separate Tabelle verwendet wird. In gewissem Sinne ist dies dieselbe MappedSuperClass, nur in einer aktualisierten Form.

Zuerst müssen Sie eine Anmerkung verwenden:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Klassen mit dieser Annotation sehen folgendermaßen aus:


@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
class User {
	int id;
	String name;
	LocalDate birthday;
}

@Entity
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}

@Entity
class Client extends User {
	String address;
}

Und separate Tabellen für jede Klasse. Zum Beispiel diese:


CREATE TABLE user {
	id INT,
	name VARCHAR,
	birthday DATE
}

CREATE TABLE employee {
	id INT,
	name VARCHAR,
	birthday DATE,
	occupation VARCHAR,
	salary INT,
	join DATE
}

CREATE TABLE client {
	id INT,
	name VARCHAR,
	birthday DATE,
	address VARCHAR
}

Der Hauptunterschied besteht darin, dass für alle Tabellen eine Pass-Through-ID (PRIMARY KEY) verwendet wird. Sie können keine unterschiedlichen Zeilen mit derselben ID haben, nicht nur innerhalb derselben Tabelle, sondern auch innerhalb dieser Tabellengruppe. Hibernate wird sich darum kümmern.

5.2 Beispiele

Es ist sehr interessant zu sehen, wie das alles funktioniert.

Sie können eine einfache HQL-Abfrage schreiben, um alle Benutzer abzurufen: Benutzer, Mitarbeiter, Kunde :

List<User> accounts = session.createQuery("from User").list();

Aber Hibernate wiederum wird eine sehr interessante Abfrage generieren. Es wird eine Auswahl aus allen Tabellen treffen, diese dann über UNION ALL zu einer Art virtuellen Tabelle zusammenfassen und erst dann suchen und/oder auswählen

Um jedoch Tabellen mit unterschiedlichen Spalten zusammenzuführen, müssen diese zunächst um gefälschte Spalten ergänzt werden. Beispielsweise muss die Benutzertabelle um Spalten ergänzt werden:

  • occupation VARCHAR
  • salary INT
  • join DATE
  • address VARCHAR

Ein Beispiel für eine SQL-Abfrage an die Benutzertabelle vor der Ausführung UNION ALL:


SELECT   id,
         name,
         birthday,
         CAST(NULL AS VARCHAR) AS occupation,
         CAST(NULL AS INT) AS salary,
         CAST(NULL AS DATE) AS join,
         CAST(NULL AS VARCHAR) AS address,
         0 AS clazz
FROM  user

Eine Beispiel-SQL-Abfrage an die Mitarbeitertabelle vor der Ausführung UNION ALL:


SELECT   id,
         name,
         birthday,
         occupation,
         salary,
         join,
         CAST(NULL AS VARCHAR) AS address,
         1 AS clazz
FROM  employee

Ein Beispiel für eine SQL-Abfrage an die Client-Tabelle vor der Ausführung UNION ALL:


SELECT  id,
        name,
        birthday,
        CAST(NULL AS VARCHAR) AS occupation,
        CAST(NULL AS INT) AS salary,
        CAST(NULL AS DATE) AS join,
        address,
        2 AS clazz
FROM client

Die gute Nachricht ist, dass HQL-Abfragen so funktionieren, wie Sie es möchten.

Die schlechte Nachricht ist, dass sie langsam sein können, wenn die Tabellen viele Daten enthalten. Denn zuerst müssen Sie Daten aus allen Tabellen auswählen, dann deren Zeilen mit kombinieren UNION ALLund erst dann filtern.