Was genau steuert die Abrufstrategie von JPA? Ich kann keinen Unterschied zwischen eifrig und faul feststellen. In beiden Fällen verbindet JPA / Hibernate nicht automatisch viele-zu-eins-Beziehungen.
Beispiel: Person hat eine einzelne Adresse. Eine Adresse kann vielen Personen gehören. Die mit JPA-Annotationen versehenen Entitätsklassen sehen folgendermaßen aus:
@Entity
public class Person {
@Id
public Integer id;
public String name;
@ManyToOne(fetch=FetchType.LAZY or EAGER)
public Address address;
}
@Entity
public class Address {
@Id
public Integer id;
public String name;
}
Wenn ich die JPA-Abfrage verwende:
select p from Person p where ...
JPA / Hibernate generiert eine SQL-Abfrage zur Auswahl aus der Personentabelle und anschließend eine eigene Adressabfrage für jede Person:
select ... from Person where ...
select ... from Address where id=1
select ... from Address where id=2
select ... from Address where id=3
Dies ist sehr schlecht für große Ergebnismengen. Bei 1000 Personen werden 1001 Abfragen generiert (1 von Person und 1000 von Adresse). Ich weiß das, weil ich mir das Abfrageprotokoll von MySQL ansehe. Nach meinem Verständnis führt das Festlegen des Abruftyps der Adresse auf eifrig dazu, dass JPA / Hibernate automatisch mit einem Join abfragt. Unabhängig vom Abruftyp werden jedoch immer noch unterschiedliche Abfragen für Beziehungen generiert.
Nur wenn ich ihm ausdrücklich sage, dass er beitreten soll, tritt er tatsächlich bei:
select p, a from Person p left join p.address a where ...
Vermisse ich hier etwas? Ich muss jetzt jede Abfrage von Hand codieren, damit sie die vielen-zu-eins-Beziehungen verbindet. Ich verwende die JPA-Implementierung von Hibernate mit MySQL.
Bearbeiten: Es scheint (siehe FAQ zum Ruhezustand hier und hier ), dass FetchType
JPA-Abfragen keine Auswirkungen haben. In meinem Fall habe ich ihm ausdrücklich gesagt, dass er beitreten soll.