2.1 opțiune de preluare
Dezvoltatorii Hibernate cunosc problema cu încărcarea entităților copil de mult timp. Deci, primul lucru pe care l-au făcut a fost să adauge un parametru de preluare special la adnotări @OneToMany
, @ManyToMany
.
Acest parametru poate lua două valori:
- DORNIC
- LENEŞ
Exemplu:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
Dacă parametrul de preluare este egal cu EAGER , atunci când entitatea părinte este încărcată, vor fi încărcate și toate entitățile sale fii. De asemenea, Hibernate va încerca să o facă într-o singură interogare SQL, generând o interogare puternică și obținând toate datele simultan.
Dacă parametrul de preluare ia valoarea LAZY , atunci când entitatea părinte este încărcată, entitatea copil nu va fi încărcată. În schimb, va fi creat un obiect proxy.
Cu ajutorul acestui obiect proxy, Hibernate va urmări accesul la această entitate copil și îl va încărca în memorie prima dată când este accesat.
Dacă ne amintim situația noastră cu comentarii:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
public List<Comment> comments;
}
Atunci ai o „alegere șic”:
Dacă fetch = FetchType.EAGER
, atunci Hibernate va încărca toate comentariile pe prima linie de cod:
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
Dacă fetch = FetchType.LAZY
, atunci Hibernate va încărca toate comentariile pe a doua linie de cod:
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here
După cum puteți ghici deja, nu aveți opțiune când nu încarcă toate comentariile :)
2.2 Valoare implicită
Dacă nu specificați o opțiune de preluare pentru @ManyTo
adnotarea..., atunci Hibernate va folosi valorile implicite.
Ele sunt ușor diferite pentru diferite tipuri de adnotări. Pentru adnotări @OneToOne
și @ManyToOne
este dornic, pentru adnotări @OneToMany
și @ManyToMany
este LENES. Este ușor de reținut - dacă ne referim la un obiect, atunci acesta va fi încărcat complet. Dacă ne referim la o colecție, atunci aceasta va fi încărcată prima dată când este accesată.
2.3 Adnotare @LazyCollection
După cum ați văzut deja, parametrul fetch nu ajută prea mult atunci când lucrați cu colecții. Creatorii Hibernate au încercat să remedieze acest lucru adăugând o adnotare specială @LazyCollection
. De obicei este scris astfel:
@LazyCollection(LazyCollectionOption.TRUE)
Trebuie să-l specificați atunci când mapați câmpurile de colecție:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
Această adnotare are un parametru de valoare care poate lua una dintre cele trei valori:
- LazyCollectionOption. ADEVĂRAT
- LazyCollectionOption. FALS
- LazyCollectionOption. SUPLIMENTAR
Primele două opțiuni sunt foarte asemănătoare cu opțiunea de preluare.
Dacă parametrul este setat la LazyCollectionOption.TRUE
, înseamnă că valorile câmpului de comentarii nu vor fi încărcate din baza de date atunci când este încărcat obiectul utilizator părinte. Obiectele de tip Comentariu vor fi încărcate la prima accesare a câmpului de comentarii. De fapt, acesta este echivalentul parametruluiFetchType.LAZY
Dacă parametrul este setat la LazyCollectionOption.FALSE
, înseamnă că valorile câmpului de comentarii vor fi încărcate din baza de date în momentul încărcării obiectului utilizator părinte. Obiectele de tip Comentariu vor fi încărcate la prima accesare a câmpului de comentarii. De fapt, acesta este echivalentul FetchType.EAGER
.