Probleme de conservare

Astăzi vom avea o schemă nouă și super interesantă - folosind caracteristicile Hibernate pentru a salva ierarhia claselor în baza de date.

O ierarhie de clase este un set de clase legate între ele printr-o relație de moștenire.

Imaginați-vă că aveți trei clase pe care doriți să le stocați în baza de date:

class User {
  int id;
  String name;
  LocalDate birthday;
}
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
class Client extends User {
   String address;
}

Clasele sunt moștenite una de la alta. Și cel mai interesant lucru este că doriți să utilizați Hibernate pentru a stoca obiecte din aceste clase în baza de date.

Tipuri de soluții

Hibernate are 4 moduri posibile prin care poate asocia o ierarhie de clase cu tabele dintr-o bază de date:

  • MappedSuperclass
  • o singură masă
  • Tabel alăturat
  • Tabel pe clasă

Fiecare strategie își asumă propria sa structură de tabel în baza de date. Uneori sunt destul de complexe. Dar interogările pentru HQL către ei sunt foarte simple. Este exact cazul în care avantajele Hibernate se manifestă clar.

Nu am auzit niciodată acești termeni traduși în rusă, așa că recomand să-i pronunți și în engleză.

Mai jos vom analiza ce înseamnă fiecare dintre ele.

@MappedSuperClass

Să începem cu cea mai simplă soluție - în baza de date aveț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
}

Numai dumneavoastră știți că clasele pentru aceste tabele sunt conectate într-o ierarhie . Dacă doriți ca Hibernate să știe și despre acest lucru, trebuie să adăugați adnotarea @MappedSuperclass la clasa părinte . Fără el, Hibernate va ignora pur și simplu câmpurile și adnotările clasei părinte.

Clasele cu această adnotare vor arăta astfel:

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

Acesta este cel mai primitiv mod de a lega ierarhia claselor și baza de date. Această abordare vă permite de fapt doar să evitați câmpurile duplicate în clase.

Interogările bazei de date în HQL vor returna doar entitatea al cărei tip este specificat în mod explicit. Nu puteți scrie o interogare de bază de date în HQL și nu puteți obține o listă cu toți utilizatorii: Utilizator, Angajat, Client.