2.1 opcja pobierania
Twórcy Hibernate od dawna wiedzieli o problemie z ładowaniem encji potomnych. Pierwszą rzeczą, jaką zrobili, było dodanie specjalnego parametru pobierania do adnotacji @OneToMany
, @ManyToMany
.
Ten parametr może przyjąć dwie wartości:
- CHĘTNY
- LENIWY
Przykład:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
Jeśli parametr pobierania jest równy EAGER , to po załadowaniu jednostki nadrzędnej wszystkie jej jednostki podrzędne również zostaną załadowane. Ponadto Hibernate spróbuje to zrobić w jednym zapytaniu SQL, generując potężne zapytanie i pobierając wszystkie dane naraz.
Jeśli parametr pobierania przyjmuje wartość LAZY , to po załadowaniu jednostki nadrzędnej jednostka podrzędna nie zostanie załadowana. Zamiast tego zostanie utworzony obiekt proxy.
Za pomocą tego obiektu proxy Hibernate będzie śledzić dostęp do tej jednostki potomnej i załadować ją do pamięci przy pierwszym dostępie.
Jeśli przypomnimy sobie naszą sytuację z komentarzami:
@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;
}
Następnie masz „szykowny wybór”:
Jeśli fetch = FetchType.EAGER
, to Hibernate załaduje wszystkie komentarze w pierwszej linii kodu:
User user = session.get(User.class, 1); // załaduj tutaj wszystkie komentarze
List<Comment> comments = user.getComments();
Jeśli fetch = FetchType.LAZY
, to Hibernate załaduje wszystkie komentarze w drugiej linii kodu:
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); // załaduj tutaj wszystkie komentarze
Jak już się domyślasz, nie masz opcji, gdy nie ładuje się wszystkich komentarzy :)
2.2 Wartość domyślna
Jeśli nie określisz opcji pobierania dla @ManyTo
adnotacji ..., Hibernacja użyje wartości domyślnych.
Są one nieco inne dla różnych typów adnotacji. Do adnotacji @OneToOne
i @ManyToOne
jest CHĘTNY, do adnotacji @OneToMany
i @ManyToMany
jest LENIWY. Łatwo to zapamiętać - jeśli odniesiemy się do jednego obiektu, to zostanie on załadowany w całości. Jeśli odwołujemy się do kolekcji, zostanie ona załadowana przy pierwszym dostępie.
2.3 Adnotacja @LazyCollection
Jak już widziałeś, parametr pobierania niewiele pomaga podczas pracy z kolekcjami. Twórcy Hibernate próbowali temu zaradzić, dodając specjalną adnotację @LazyCollection
. Zwykle jest to napisane tak:
@LazyCollection(LazyCollectionOption.TRUE)
Musisz to określić podczas mapowania pól kolekcji:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
Ta adnotacja ma parametr wartości, który może przyjąć jedną z trzech wartości:
- Opcja Leniwej Kolekcji. PRAWDA
- Opcja Leniwej Kolekcji. FAŁSZ
- Opcja Leniwej Kolekcji. DODATKOWY
Pierwsze dwie opcje są bardzo podobne do opcji pobierania.
Jeśli parametr jest ustawiony na LazyCollectionOption.TRUE
, oznacza to, że wartości pola komentarzy nie zostaną załadowane z bazy danych podczas ładowania nadrzędnego obiektu User. Obiekty typu Komentarz zostaną załadowane przy pierwszym dostępie do pola komentarzy. W rzeczywistości jest to odpowiednik parametruFetchType.LAZY
Jeśli parametr jest ustawiony na LazyCollectionOption.FALSE
, oznacza to, że wartości pola komentarzy zostaną wczytane z bazy danych w momencie wczytywania nadrzędnego obiektu User. Obiekty typu Komentarz zostaną załadowane przy pierwszym dostępie do pola komentarzy. W rzeczywistości jest to odpowiednik FetchType.EAGER
.
GO TO FULL VERSION