Hibernate ВСЕГДА возвращает тип фактического постоянного объекта. Если вы сохранили «MyClubUser», он будет возвращен как «MyClubUser», а не «Пользователь». Причина этого совершенно ясна - если бы Hibernate вернул «MyClubUser» как «Пользователь» и вы бы сохранили его снова, вы потеряете все дополнительные свойства, определенные в «MyClubUser».
Для этого Hibernate должен знать, что это за тип. Для стратегии InheritanceType.JOINED
единственный способ выяснить это - проверить все таблицы в иерархии наследования (ну, технически это все таблицы на текущем уровне или ниже, плюс все таблицы выше текущего уровня в текущей ветви дерева). ). Итак, если у вас есть иерархия вроде:
Root
/ \
Node1 Node2
/ \
Node11 Node12
и вы пытаетесь выбрать из root, Hibernate выполнит внешнее объединение для ВСЕХ таблиц. Если вы выбираете из Node1, Hibernate выполнит внутреннее соединение на Node1 и Root плюс внешнее соединение на Node11 и Node12. Node2 не будет затронут, потому что он не является потомком Node1.
Что касается накладных расходов на внешнее объединение - да, определенно накладные расходы, но это цена, которую вы платите за объединенную стратегию. Вы можете использовать дискриминаторы, чтобы избежать этого, но это имеет свои побочные эффекты. Является ли эти издержки значительными или нет, зависит от глубины и распространенности вашей иерархии, ваших индексов и многих других вещей. Прослушайте предложение KLE и профилируйте его.