5.1 Beskrivelse

Og til slutt, den siste strategien er Tabell per klasse. Det betyr at en egen tabell vil bli brukt for hver klasse. På en måte er dette den samme MappedSuperClass, bare i en oppdatert form.

Først må du bruke en merknad:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Klasser med denne merknaden vil se slik ut:


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

Hovedforskjellen er at en pass-through id (PRIMARY KEY) brukes for alle tabeller. Du kan ikke ha forskjellige rader med samme id, ikke bare innenfor samme tabell, men også innenfor denne gruppen av tabeller. Hibernate tar seg av dette.

5.2 Eksempler

Det er veldig interessant å se hvordan det hele fungerer.

Du kan skrive en enkel HQL-spørring for å få alle brukere: bruker, ansatt, klient :

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

Men Hibernate vil på sin side generere en veldig interessant spørring. Den vil gjøre et valg fra alle tabeller, deretter kombinere den gjennom UNION ALL til en slags virtuell tabell, og først da vil den søke og/eller velge

Men for å slå sammen tabeller med forskjellige kolonner, må de først suppleres med falske kolonner. For eksempel må brukertabellen suppleres med kolonner:

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

Et eksempel på en SQL-spørring til brukertabellen før kjøring 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-spørring til ansatttabellen før utfø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-spørring til klienttabellen før kjøring 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 nyheten er at HQL-spørringer vil fungere slik du vil at de skal.

Den dårlige nyheten er at de kan være trege hvis det er mye data i tabellene. Fordi først må du velge data fra alle tabellene, deretter kombinere radene deres med UNION ALL, og først deretter filtrere.