Postaram się wyjaśnić w wielkim skrócie, FetchType
to jest rodzaj żądania, czy dane mają być załadowane wcześniej czy leniwie, jeszcze nie mówimy nic o zapytaniach SQL pod spodem. Jak jest EAGER
to po JPA zapewnia, że po wyjściu z transakcji obiekt będzie załadowany, jak LAZY
to taka obietnica nie musi być spełniona. I tyle. A teraz FetchMode
mówi w jaki sposób pod spodem zapytania mają zostać wykonane jeśli dojdzie do ładowania elementów. Czyli FetchType
mówi o efekcie końcowym, a FetchMode
w jaki sposób dojść do żądanego efektu. Teraz porozmawiajmy o encjach zarządzanych. Jeśli w transakcji jakiś obiekt został już załadowany to nie jest on ładowany drugi raz, ponieważ hibernate pobiera go sobie z cache. Czyli jakbyś najpierw w jednej transakcji pobrał listę postów po id topicu, a następnie pobrałbyś sam topic to w zapytaniach SQL zauważyłbyś, że podczas pobierania topicu posty nie są pobierane, ponieważ hibernate wie, że ma te obiekty z cache'a. Można powiedzieć, że cache hibernate to takie hashmapy na każdy typ encji, gdzie kluczem są ID encji, a wartością encje. Jak encja znajduje się w hashmapie to znaczy, że jest zarządzana. Jak już coś zostało załadowane w transakcji to nie ładuje tego drugi raz (chyba że obiekt się zmienił i znowu zostało wywołane jakieś zapytanie wybierające dane, ale to inny temat). Hibernate nie stawia na szybkość, tylko na nieprzejmowanie się przez programistę synchronizacją obiektów pomiędzy aplikacją a bazą danych. A teraz trochę taka moja rada, wrzucanie do encji informacji, czy jej pola mają być ładowane LAZY czy EAGER zmieniając domyślne zachowania spowoduje, że potem jakbyś chciał wyświetlić listę topiców to pod spodem dla każdego topica załadujesz całą listę postów, a potem pewnie i całą listę komentarzy. I to dla każdego użycia encji w aplikacji. Proponuję użyć EntityGraph, tam jako parametr w zapytaniu go podajesz, i na każdy przypadek możesz mieć zapytania wyciągające obiekt z załadowanymi polami albo nie. A druga sprawa to polecałbym robienie jak najbardziej płaskiego dto jak się tylko da, bez zagnieżdżania pod spodem obiektów, niech frontend dociąga sobie dwoma wołaniami CQRS, najpierw listę topiców, potem po wejściu na topic po topic id niech dociągnie listę postów.