5.1 Beskrivelse

Og endelig er den sidste strategi Tabel pr. klasse. Det betyder, at der vil blive brugt en separat tabel for hver klasse. I en vis forstand er dette den samme MappedSuperClass, kun i en opdateret form.

Først skal du bruge en anmærkning:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Klasser med denne annotering vil se sådan ud:


@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;
}

Og separate tabeller for hver klasse. For eksempel disse:


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
}

Den største forskel er, at et pass-through-id (PRIMARY KEY) bruges til alle tabeller. Du kan ikke have forskellige rækker med samme id, ikke kun i den samme tabel, men også inden for denne gruppe af tabeller. Hibernate vil tage sig af dette.

5.2 Eksempler

Det er meget interessant at se, hvordan det hele fungerer.

Du kan skrive en simpel HQL-forespørgsel for at få alle brugere: Bruger, Medarbejder, Klient :

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

Men Hibernate vil til gengæld generere en meget interessant forespørgsel. Det vil foretage et valg fra alle tabeller, derefter kombinere det gennem UNION ALL til en slags virtuel tabel, og først derefter vil det søge og/eller vælge

Men for at flette tabeller med forskellige kolonner, skal de først suppleres med falske kolonner. For eksempel skal brugertabellen suppleres med kolonner:

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

Et eksempel på en SQL-forespørgsel til brugertabellen før udførelse 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

Et eksempel på SQL-forespørgsel til medarbejdertabellen før udførelse UNION ALL:


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

Et eksempel på en SQL-forespørgsel til klienttabellen før udførelse 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

Den gode nyhed er, at HQL-forespørgsler vil fungere, som du vil have dem til.

Den dårlige nyhed er, at de kan være langsomme, hvis der er mange data i tabellerne. For først skal du vælge data fra alle tabeller, derefter kombinere deres rækker med UNION ALL, og først derefter filtrere.