Skuteczność strategii dziedziczenia tabeli na subklasę Hibernate

Myślę o układzie tabeli dla hierarchii klas zarządzanych przez Hibernate i na pewno tabela dla techniki podklasy wydaje mi się najbardziej odpowiednia w sensie ogólnym. Jednak myśląc o logice, mam pewne obawy co do jej wydajności, zwłaszcza jeśli chodzi o liczbę skal podklas.

Aby podać bardzo krótki (i klasyczny) przykład, powiedzmy, że masz następujące klasy:

public abstract class Animal {
   int pkey;
   String name;
}

public class Dog extends Animal {
   long numSlippersChewed; // int is not large enough...
}

public class Cat extends Animal {
   short miceCaught; // ... but here int is far bigger than required :-)
}

(Ja eliding getters i setters i mapowania Hibernate itp., Załóżmy, że są podstawowym oczywistym przypadkiem).

Tabele bazy danych dla tych jednostek mają sens, masz ładną denormalizację i tak dalej. Jednak jakie zapytanie wykonuje Hibernate w celu wyciągnięcia pojedynczego zwierzęcia? Mogę pomyśleć o co najmniej dwóch przypadkach, w których może się to zdarzyć:

Pewna inna jednostka mająca mapowanie jeden do jednego (lub jeden do wielu), takie jak apet pole aHuman klasa. Spowoduje to zapisanie pkey, więc gdy Hibernate pobierze obiekt Human, będzie musiał pobrać odpowiedniAnimal obiekt też. Kiedy otrzymamy pkey zwierzęcia, jakie zapytanie (hase) użyje do hibernacji w celu wyodrębnienia i unieważnienia rzeczywistych danych zwierzęcia, biorąc pod uwagę, że może ono znajdować się wCat lubDog stoły?HQL taki jakfrom Animal where name='Rex' (załóżmy, że nazwy są unikalne). Jest to podobne do powyższego, ponieważ pozwala zidentyfikować wiersz w tabeli nadklasy, ale nie wiesz, która tabela podklasy ma zostać sprawdzona w celu uzyskania dalszych szczegółów. Czy HQL pozwala nawet na wysyłanie zapytańfrom klasa abstrakcyjna? (Używanie rzeczy specyficznych dla podklasy działa dobrze, np.from Cat where miceCaught > 5).

Mogę pomyśleć o dwóch sposobach, w których można to zrobić w SQL i żadna z nich nie wydaje się ładna. Jednym z nich jest uruchomienieexists zapytanie o każdą tabelę podklasy dla danego pkey, a następnie wczytanie z tabeli, która zwróciła trafienie. Alternatywnie Hibernate może wykonać okropne połączenie kwerendy związkowej we wszystkich tabelach - zasadniczo symulując schemat tabeli na hierarchię, ponieważ zestaw wyników będzie zawierał atrybuty dla wszystkich możliwych podklas z poszczególnymi zaznaczeniami z zwracanych tabel podklasynull za nieistotne argumenty. Ten ostatni przypadek prawdopodobnie nawet musiałby dodać syntetyczną kolumnę dyskryminatora, aby Hibernate mógł wiedzieć, która tabela podklasy faktycznie zwróciła wiersz, a zatem jaka klasa Java powinna zostać przeanalizowana.

Sprawy stają się coraz bardziej skomplikowane, jeśli masz podtypy konkretnych typów:

public class Greyhound extends Dog {
   float lifetimeRacingWinnings;
}

Teraz dla danego klawisza zwierzęcia mogą być prawidłowe wiersze wDog i Greyhound tabele, co oznacza, że ​​moje pierwsze podejście do ręcznego sprawdzania klasy odpowiadającej pkey staje się dużo trudniejsze.

Powodem, dla którego tak bardzo mnie to niepokoi, jest to, że będę chciał użyć tego podejścia w hierarchii klas z około 70 klasami z maksymalnym łańcuchem zagnieżdżenia 4-5 poziomów, więc wykonanie zapytania o związek na to wszystko prawdopodobnie będzieokropny wydajność. Czy Hibernate ma jakieś sztuczki w rękawie, aby utrzymać ten względnie wydajny? Czy ładowanie odniesienia do jednej z tych klas przez pkey zajmuje dużo czasu?

questionAnswers(3)

yourAnswerToTheQuestion