5.1 Descriere

Și, în sfârșit, ultima strategie este Tabel pe clasă. Înseamnă că va fi folosit un tabel separat pentru fiecare clasă. Într-un fel, acesta este același MappedSuperClass, doar într-o formă actualizată.

Mai întâi, trebuie să utilizați o adnotare:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Clasele cu această adnotare vor arăta astfel:


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

Și tabele separate pentru fiecare clasă. De exemplu, acestea:


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
}

Principala diferență este că pentru toate tabelele se folosește un ID de trecere (CHEie PRIMARĂ). Nu puteți avea rânduri diferite cu același id, nu numai în cadrul aceluiași tabel, ci și în cadrul acestui grup de tabele. Hibernate se va ocupa de asta.

5.2 Exemple

Este foarte interesant de văzut cum funcționează totul.

Puteți scrie o interogare simplă HQL pentru a obține toți utilizatorii: utilizator, angajat, client :

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

Dar Hibernate, la rândul său, va genera o interogare foarte interesantă. Va face o selecție din toate tabelele, apoi o va combina prin UNION ALL într-un fel de tabel virtual și abia apoi va căuta și/sau selecta

Dar pentru a îmbina tabelele cu coloane diferite, acestea trebuie mai întâi completate cu coloane false. De exemplu, tabelul utilizatorilor trebuie completat cu coloane:

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

Un exemplu de interogare SQL către tabelul utilizator înainte de execuție 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 exemplu de interogare SQL către tabelul angajat înainte de execuție UNION ALL:


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

Un exemplu de interogare SQL către tabelul client înainte de execuție 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

Vestea bună este că interogările HQL vor funcționa așa cum doriți.

Vestea proastă este că pot fi lente dacă există multe date în tabele. Pentru că mai întâi trebuie să selectați datele din toate tabelele, apoi să combinați rândurile acestora cu UNION ALL, și abia apoi să filtrați.