Co dokładnie kontroluje strategia pobierania JPA? Nie potrafię dostrzec różnicy między chętnym a leniwym. W obu przypadkach JPA / Hibernate nie łączy automatycznie relacji „wiele do jednego”.
Przykład: osoba ma jeden adres. Adres może należeć do wielu osób. Klasy jednostek z adnotacjami JPA wyglądają następująco:
@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;
}
Jeśli używam zapytania JPA:
select p from Person p where ...
JPA / Hibernate generuje jedno zapytanie SQL do wyboru z tabeli Person, a następnie odrębne zapytanie adresowe dla każdej osoby:
select ... from Person where ...
select ... from Address where id=1
select ... from Address where id=2
select ... from Address where id=3
Jest to bardzo złe w przypadku dużych zestawów wyników. Jeśli jest 1000 osób, generuje 1001 zapytań (1 od osoby i 1000 niezależnie od adresu). Wiem o tym, ponieważ patrzę na dziennik zapytań MySQL. Zrozumiałem, że ustawienie typu pobierania adresu na chętny spowoduje, że JPA / Hibernate automatycznie zapyta o sprzężenie. Jednak niezależnie od typu pobierania nadal generuje odrębne zapytania dotyczące relacji.
Dopiero gdy wyraźnie powiem mu, aby dołączył, faktycznie dołączy:
select p, a from Person p left join p.address a where ...
Czy coś mi umyka? Teraz muszę ręcznie zakodować każde zapytanie, aby zostało dołączone do relacji „wiele do jednego”. Używam implementacji JPA Hibernate z MySQL.
Edycja: Wygląda na to, że (patrz FAQ Hibernacji tutaj i tutaj ) FetchType
nie wpływa na zapytania JPA. Więc w moim przypadku wyraźnie nakazałem mu dołączyć.