2.1 Abrufoption
Den Entwicklern von Hibernate ist das Problem beim Laden untergeordneter Entitäten schon seit langem bekannt. Als erstes fügten sie den Anmerkungen einen speziellen Abrufparameter@OneToMany
hinzu .@ManyToMany
Dieser Parameter kann zwei Werte annehmen:
- ERPICHT
- FAUL
Beispiel:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
Wenn der Abrufparameter gleich EAGER ist , werden beim Laden der übergeordneten Entität auch alle ihre untergeordneten Entitäten geladen. Außerdem wird Hibernate versuchen, dies in einer einzigen SQL-Abfrage zu erledigen, indem es eine umfangreiche Abfrage generiert und alle Daten auf einmal abruft.
Wenn der Abrufparameter den Wert LAZY annimmt , wird beim Laden der übergeordneten Entität die untergeordnete Entität nicht geladen. Stattdessen wird ein Proxy-Objekt erstellt.
Mit Hilfe dieses Proxy-Objekts verfolgt Hibernate den Zugriff auf diese untergeordnete Entität und lädt sie beim ersten Zugriff in den Speicher.
Wenn wir uns mit Kommentaren an unsere Situation erinnern:
@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;
}
Dann haben Sie eine „schicke Wahl“:
Wenn fetch = FetchType.EAGER
, dann lädt Hibernate alle Kommentare in der ersten Codezeile:
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
Wenn fetch = FetchType.LAZY
, dann lädt Hibernate alle Kommentare in der 2. Codezeile:
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here
Wie Sie bereits erraten können, haben Sie keine Option, wenn nicht alle Kommentare geladen werden :)
2.2 Standardwert
Wenn Sie für die Annotation ... keine Abrufoption angeben @ManyTo
, verwendet Hibernate die Standardwerte.
Sie unterscheiden sich geringfügig für verschiedene Anmerkungstypen. Für Anmerkungen @OneToOne
und @ManyToOne
ist EIGER, für Anmerkungen @OneToMany
und @ManyToMany
ist FAUL. Es ist leicht zu merken: Wenn wir auf ein Objekt verweisen, wird es vollständig geladen. Wenn wir auf eine Sammlung verweisen, wird diese beim ersten Zugriff geladen.
2.3 @LazyCollection-Annotation
Wie Sie bereits gesehen haben, hilft der fetch-Parameter bei der Arbeit mit Sammlungen nicht viel. Die Ersteller von Hibernate haben versucht, dies zu beheben, indem sie eine spezielle Anmerkung hinzugefügt haben @LazyCollection
. Normalerweise wird es so geschrieben:
@LazyCollection(LazyCollectionOption.TRUE)
Sie müssen es beim Zuordnen von Sammlungsfeldern angeben:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
Diese Annotation verfügt über einen Wertparameter, der einen von drei Werten annehmen kann:
- LazyCollectionOption. WAHR
- LazyCollectionOption. FALSCH
- LazyCollectionOption. EXTRA
Die ersten beiden Optionen sind der Fetch-Option sehr ähnlich.
Wenn der Parameter auf eingestellt ist LazyCollectionOption.TRUE
, bedeutet dies, dass die Werte des Kommentarfelds nicht aus der Datenbank geladen werden , wenn das übergeordnete Benutzerobjekt geladen wird. Objekte vom Typ Kommentar werden beim ersten Zugriff auf das Kommentarfeld geladen. Tatsächlich ist dies das Äquivalent des ParametersFetchType.LAZY
Wenn der Parameter auf eingestellt ist LazyCollectionOption.FALSE
, bedeutet dies, dass die Werte des Kommentarfelds zum Zeitpunkt des Ladens des übergeordneten Benutzerobjekts aus der Datenbank geladen werden . Objekte vom Typ Kommentar werden beim ersten Zugriff auf das Kommentarfeld geladen. Tatsächlich ist dies das Äquivalent von FetchType.EAGER
.