hibernate
Podnoszenie wydajności
Szukaj…
Nie używaj typu pobierania EAGER
Hibernacja może używać dwóch rodzajów pobierania, gdy mapujesz relacje między dwoma bytami: EAGER
i LAZY
.
Ogólnie rzecz biorąc, typ pobierania EAGER
nie jest dobrym pomysłem, ponieważ nakazuje JPA zawsze pobierać dane, nawet gdy te dane nie są konieczne.
Na przykład, jeśli masz encję Person
i relację z Address
ten sposób:
@Entity
public class Person {
@OneToMany(mappedBy="address", fetch=FetchType.EAGER)
private List<Address> addresses;
}
Za każdym razem, gdy zapytasz o Person
, zostanie również zwrócona lista Address
tej Person
.
Zamiast mapować swój byt za pomocą:
@ManyToMany(mappedBy="address", fetch=FetchType.EAGER)
Posługiwać się:
@ManyToMany(mappedBy="address", fetch=FetchType.LAZY)
Kolejną rzeczą, na którą należy zwrócić uwagę, są relacje @OneToOne
i @ManyToOne
. Oba są domyślnie EAGER. Jeśli więc obawiasz się o wydajność aplikacji, musisz ustawić pobieranie dla tego typu relacji:
@ManyToOne(fetch=FetchType.LAZY)
I:
@OneToOne(fetch=FetchType.LAZY)
Użyj kompozycji zamiast dziedziczenia
Hibernacja ma pewne strategie dziedziczenia. Typ dziedziczenia JOINED
wykonuje JOIN między jednostką podrzędną a jednostką nadrzędną.
Problem z tym podejściem polega na tym, że Hibernacja zawsze przenosi dane wszystkich zaangażowanych tabel w dziedziczenie.
Na przykład, jeśli masz jednostki Bicycle
i Bicycle
MountainBike
używając typu Dziedziczenie JOINED
:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Bicycle {
}
I:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class MountainBike extends Bicycle {
}
Każde zapytanie JPQL, które trafi w MountainBike
, przyniesie dane Bicycle
, tworząc zapytanie SQL, takie jak:
select mb.*, b.* from MountainBike mb JOIN Bicycle b ON b.id = mb.id WHERE ...
Jeśli masz innego rodzica dla Bicycle
(na przykład Transport
), powyższe zapytanie przyniesie również dane od tego rodzica, wykonując dodatkowe DOŁĄCZ.
Jak widać, jest to również rodzaj mapowania EAGER
. Nie masz wyboru, aby przynieść tylko dane tabeli MountainBike
przy użyciu tej strategii dziedziczenia.
Najlepszą wydajnością jest użycie kompozycji zamiast dziedziczenia.
Aby to osiągnąć, możesz zmapować jednostkę MountainBike
, aby mieć bicycle
terenowy:
@Entity
public class MountainBike {
@OneToOne(fetchType = FetchType.LAZY)
private Bicycle bicycle;
}
I Bicycle
:
@Entity
public class Bicycle {
}
Każde zapytanie przyniesie teraz domyślnie tylko dane MountainBike
.