2.1 hentealternativ
Utviklerne av Hibernate har visst om problemet med å laste inn underordnede enheter i lang tid. Så det første de gjorde var å legge til en spesiell henteparameter til merknadene @OneToMany
.@ManyToMany
Denne parameteren kan ha to verdier:
- IVRIG
- LAT
Eksempel:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
Hvis henteparameteren er lik EAGER , vil alle dens underordnede enheter også lastes inn når den overordnede enheten er lastet. Hibernate vil også prøve å gjøre det i én SQL-spørring, generere en heftig spørring og hente alle dataene samtidig.
Hvis henteparameteren tar verdien LAZY , vil den underordnede enheten ikke lastes inn når den overordnede enheten er lastet. I stedet opprettes et proxy-objekt.
Ved hjelp av dette proxy-objektet vil Hibernate spore tilgangen til denne underordnede enheten og laste den inn i minnet første gang den åpnes.
Hvis vi husker vår situasjon med kommentarer:
@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;
}
Da har du et "elegant valg":
Hvis fetch = FetchType.EAGER
, vil Hibernate laste inn alle kommentarer på den første kodelinjen:
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
Hvis fetch = FetchType.LAZY
, vil Hibernate laste inn alle kommentarene på den andre kodelinjen:
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here
Som du allerede kan gjette, har du ikke noe valg når det ikke laster inn alle kommentarene :)
2.2 Standardverdi
Hvis du ikke spesifiserer et hentealternativ for @ManyTo
...-kommentaren, vil Hibernate bruke standardverdiene.
De er litt forskjellige for forskjellige merknadstyper. For merknader @OneToOne
og @ManyToOne
er ivrig, for merknader @OneToMany
og @ManyToMany
er LATEN. Det er lett å huske - hvis vi refererer til ett objekt, vil det bli lastet helt. Hvis vi refererer til en samling, vil den bli lastet inn første gang den åpnes.
2.3 @LazyCollection-kommentar
Som du allerede har sett, hjelper ikke appetch-parameteren mye når du jobber med samlinger. Skaperne av Hibernate prøvde å fikse dette ved å legge til en spesiell merknad @LazyCollection
. Det skrives vanligvis slik:
@LazyCollection(LazyCollectionOption.TRUE)
Du må spesifisere det når du kartlegger samlingsfelt:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
Denne merknaden har en verdiparameter som kan ha en av tre verdier:
- LazyCollectionOption. EKTE
- LazyCollectionOption. FALSK
- LazyCollectionOption. EKSTRA
De to første alternativene ligner veldig på hentealternativet.
Hvis parameteren er satt til LazyCollectionOption.TRUE
, betyr det at verdiene til kommentarfeltet ikke vil bli lastet fra databasen når det overordnede brukerobjektet lastes. Objekter av typen Kommentar vil bli lastet inn første gang du får tilgang til kommentarfeltet. Faktisk tilsvarer dette parameterenFetchType.LAZY
Hvis parameteren er satt til LazyCollectionOption.FALSE
, betyr det at verdiene til kommentarfeltet vil bli lastet fra databasen på tidspunktet for lasting av det overordnede brukerobjektet. Objekter av typen Kommentar vil bli lastet inn første gang du får tilgang til kommentarfeltet. Faktisk tilsvarer dette FetchType.EAGER
.