Я использую, в спящем режиме для соединения с моей базой данных. У меня есть структура наследования в моем приложении. Проблема состоит в том, что, когда я делаю запрос как "от Животного", оно делает оставленное внешнее объединение для класса Животное, его sub классы и все ассоциации для Животного и его подклассов. Как я избегаю этой ситуации. Я хочу загрузить данные только, когда я указываю его через fetchmode в моем запросе критериев?
Да, Hibernate поддерживает полиморфные запросы. Из документации:
14.8. Полиморфные запросы
Запрос типа:
from Cat as cat
возвращает экземпляры не только
Cat
, но и также подклассов, таких какDomesticCat
. Запросы Hibernate могут называть любой Java класс или интерфейс в предложении from. Запрос вернет экземпляры всех постоянных классов, которые расширяют этот класс или реализуют интерфейс. Например, следующий запрос вернет все постоянные объекты:from java.lang.Object o
Интерфейс
Named
может быть реализован различными постоянными классами:from Named n, Named m where n.name = m.name
Эти два последних запроса потребуют более одного SQL
SELECT
. Это означает что предложение order by не правильно упорядочивает весь набор результатов. Это также означает, что вы не можете вызвать эти запросы с помощьюQuery.scroll()
.
Это поведение по умолчанию (называется неявный полиморфизм), а Hibernate поддерживает как неявный, так и явный полиморфизм:
Неявный полиморфизм означает, что экземпляры класса будут возвращены запросом, который называет любой суперкласс или реализованный интерфейс или класс, и что экземпляры любого подкласса класса будут возвращены по запросу, который называет сам класс сам. Явный полиморфизм означает. что экземпляры класса будут возвращены только по запросам, которые явно называют этот класс. Запросы с именем класс, будут возвращать только экземпляры подклассов, отображенных внутри этого
<класс>
объявления какor
. Для большинства целей по умолчанию
polymorphism="implicit"
is подходящим. Явный полиморфизм полезен, когда два разных класса отображаются на одну и ту же таблицу. Это позволяет создать "облегченный" класс, который содержит подмножество столбцов таблицы.
Это можно настроить на уровне класса. Используйте polymorphism="explicit"
, если вы используете xml сопоставления, см. 5.1.3 Class. Используйте аннотацию Hibernate @Entity
, если вы используете аннотации, см. 2.4.1. Entity. Ниже приведен пример:
@javax.persistence.Entity
@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)
@Inheritance(strategy = InheritanceType.JOINED)
public class Foo {
...
}
Предположим, у вас есть следующая структура классов:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
тогда, когда вы выберете все Animal
, вы также должны будете загрузить все Dog
] s и Cat
s. В конце концов, они Животные
.
Другое дело - ассоциации. Вы можете создавать свои сопоставления так, чтобы ассоциации загружались ленивой, а не активной загрузкой.
По сути, это стандартный шаблон проектирования наследования ORM, используемый Hibernate, который называется наследованием классов (все классы отображаются в одной таблице), если вы хотите изменить это, вы можете погуглить:
- отдельная иерархия классов или таблица для каждого класса (это отобразит каждый класс в отдельную таблицу в БД)
- конкретная иерархия классов (это отобразит в таблицу только конкретные реализации).