Problem Hibernate n+1 zapytań
Problem Hibernate n+1 zapytań
Problem Hibernate n+1 zapytań (generowanie nadmiarowych zapytań) jest jednym z najbardziej znanych problemów, z jakimi muszą zmagać się programiści wykorzystujący w swoich projektach Hibernate. Kiedy kolekcja ładowana jest leniwie (Lazy loading) to hibernate zamiast jednego zapytania wykonuje n + 1 zapytań. Jedno zapytanie do pobrania listy obiektów zawierających wspomniane kolekcje oraz n zapytań do pobrania każdej kolekcji dla każdego pobranego wcześnie obiektu.
@Entity public class Room { @Id @GeneratedValue private long id; @OneToMany private List <Item > items ; // getters & setters } @Entity public class Item { @Id @GeneratedValue private long id; private String name ; // getters & setters }
Dla każdego z N pokoi wykonywane jest zapytanie o jego przedmioty (N razy przedmioty + 1 raz pokoje, w sumie N+1 zapytań)
Hibernate : select room0_ .id as id1_17_ from room_n_1_problem room0_ Hibernate : select items0_ . room as room3_9_0_ , items0_ .id as id1_9_0_ , items0_ .id as id1_9_1_ , items0_ . name as name2_9_1_ , items0_ . room as room3_9_1_ from item_n_1_problem items0_ where items0_ . room =? Hibernate : select items0_ . room as room3_9_0_ , items0_ .id as id1_9_0_ , items0_ .id as id1_9_1_ , items0_ . name as name2_9_1_ , items0_ . room as room3_9_1_ from item_n_1_problem items0_ where items0_ . room =?
Rozwiązanie? Stworzenie zapytania z użyciem klauzuli JOIN FETCH:
SELECT DISTINCT u FROM Room r JOIN FETCH r. items
lub od JPA 2.1 wykorzystanie bardziej wyrafinowanej metody z użyciem adnotacji @NamedEntityGraphs.
Leave a comment