5.1 Descrizione

E infine, l'ultima strategia è Tabella per classe. Significa che verrà utilizzata una tabella separata per ogni classe. In un certo senso, questa è la stessa MappedSuperClass, solo in una forma aggiornata.

Innanzitutto, devi utilizzare un'annotazione:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Le classi con questa annotazione avranno questo aspetto:


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

E tavoli separati per ogni classe. Ad esempio, questi:


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
}

La differenza principale è che un ID pass-through (PRIMARY KEY) viene utilizzato per tutte le tabelle. Non puoi avere righe diverse con lo stesso id, non solo all'interno della stessa tabella, ma anche all'interno di questo gruppo di tabelle. Hibernate si prenderà cura di questo.

5.2 Esempi

È molto interessante vedere come funziona il tutto.

Puoi scrivere una semplice query HQL per ottenere tutti gli utenti: Utente, Impiegato, Cliente :

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

Ma Hibernate, a sua volta, genererà una query molto interessante. Effettuerà una selezione da tutte le tabelle, quindi la combinerà tramite UNION ALL in una sorta di tabella virtuale, e solo allora cercherà e/o selezionerà

Ma per unire tabelle con colonne diverse, devono prima essere integrate con colonne false. Ad esempio, la tabella utente deve essere integrata con colonne:

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

Un esempio di una query SQL alla tabella utente prima dell'esecuzione 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

Un esempio di query SQL alla tabella dei dipendenti prima dell'esecuzione UNION ALL:


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

Un esempio di query SQL alla tabella client prima dell'esecuzione 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

La buona notizia è che le query HQL funzioneranno nel modo desiderato.

La cattiva notizia è che possono essere lenti se ci sono molti dati nelle tabelle. Perché prima devi selezionare i dati da tutte le tabelle, quindi combinare le loro righe con UNION ALLe solo successivamente filtrare.