Эффективность стратегии наследования таблиц на подклассы Hibernate

Я думаю о макете таблицы для иерархии классов, управляемой Hibernate, и, конечно, метод таблицы на подклассы кажется мне наиболее подходящим в общем смысле. Однако, продумывая логику, я испытываю некоторые опасения по поводу ее производительности, особенно в том, что касается количества подклассов.

Чтобы привести очень краткий (и классический) пример, давайтескажем, у вас есть следующие классы:

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 :-)
}

(Я'я выбираю геттеры и сеттеры, отображения Hibernate и т. д., просто предположим, что ониосновной очевидный случай).

Таблицы базы данных для этих сущностей имеют смысл, вы получаете хорошую денормализацию и так далее. Однако, какой запрос делает Hibernate, чтобы вытащить отдельное животное? Я могу вспомнить как минимум два случая, когда это может произойти:

Некоторый другой объект, имеющий отображение один-к-одному (или один-ко-многим), такой какpet полеHuman учебный класс. Это сохранит pkey, поэтому, когда Hibernate выбирает объект Human, ему нужно будет извлечь соответствующийAnimal объект тоже. Когда задан pkey животного, какой запрос (ы) будет использовать Hibernate для извлечения и отмены сортировки фактических данных Animal, учитывая, что они могут находиться вCat или жеDog таблицы?HQL, такой какfrom Animal where name='Rex' (позволять'Предположим, что имена являются уникальными). Это похоже на вышесказанное в том, что оно позволяет вам идентифицировать строку в таблице суперкласса, но вы нене знаю, какую таблицу подкласса нужно проверить для получения более подробной информации. Позволяет ли HQL даже выдавать запросfrom абстрактный класс? (Использование специфичных для подклассов вещей работает хорошо, хотя, например,from Cat where miceCaught > 5).

Я могу придумать два способа, которыми это можно сделать в SQL, и ни один из них не выглядит симпатичным. Одним из них является запускexists запрос к каждой таблице подкласса для данного ключа и затем загрузить из таблицы, которая вернула попадание. В качестве альтернативы Hibernate мог бы выполнить какое-то ужасное объединение запросов объединения во всех таблицах - по сути, имитируя схему таблицы на иерархию, в которой результирующий набор будет включать атрибуты для всех возможных подклассов с отдельными выборками из таблиц подклассов, возвращающимиnull за неактуальные аргументы. В последнем случае, возможно, даже потребуется добавить синтетический столбец дискриминатора, чтобы Hibernate мог знать, какая таблица подклассов действительно вернула строку и, следовательно, в какой класс Java они должны быть проанализированы.

Вещи становятся более опасными, если у вас есть подтипы конкретных типов:

public class Greyhound extends Dog {
   float lifetimeRacingWinnings;
}

Теперь для данного животного pkey, вDog а также Greyhound таблицы, это означает, что мой первый подход вручную проверять класс, который соответствует pkey, становится намного сложнее.

Причина яЯ очень обеспокоен тем, что я захочу использовать этот подход в иерархии классов с примерно 70 классами с максимальной цепочкой вложений 4-5 уровней, поэтому выполнение запроса объединения для всего этого, вероятно, будет иметькакой ужас спектакль. Есть ли у Hibernate какие-то хитрости, чтобы сохранить это относительно быстрым? Или загрузка ссылки на один из этих классов с помощью pkey займет много времени?

Ответы на вопрос(3)

Ваш ответ на вопрос