Подтвердить что ты не робот

Как выполнить неполиморфный запрос HQL в Hibernate?

Я использую Hibernate 3.1.1, и, в частности, я использую запросы HQL.

В соответствии с документацией запросы Hibernate являются полиморфными:

Запрос типа: from Cat as cat возвращает экземпляры не только Cat, но и подклассы типа DomesticCat.

Как я могу запросить экземпляры Cat, но не любого из его подклассов?

Я хотел бы иметь возможность сделать это без явного упоминания каждого подкласса.

Я знаю следующие варианты и не считаю их удовлетворительными:

  • Ручная фильтрация экземпляров после запроса OR:
  • Вручную добавление предложения WHERE в столбце дискриминатора.

Для Hibernate было бы разумно разрешить пользователю решать, должен ли запрос быть полиморфным или нет, но я не могу найти такой вариант.

Спасибо заранее!

4b9b3361

Ответ 1

Используйте polymorphism="explicit" в сопоставление классов. Это заставит запросы возвращать только экземпляры именованного класса, а не его подклассы.

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

Ответ 2

SELECT cat FROM Cat cat WHERE cat.class='cat'

где значение 'cat' является значением дискриминатора класса Cat.

Если вы используете TABLE_PER_CLASS, попробуйте cat.class='Cat') (имя класса)

Это не является категорией where в столбце дискриминатора, потому что такой запрос будет терпеть неудачу (столбец дискриминатора доступен только в собственных запросах).

Ответ 3

JPA 2 (Hibernate 3.5) добавляет поддержку не полиморфных запросов, это очень похоже на свойство Hibernates.class(как ответил Божо), но он не является Hibernate. Это делается с помощью оператора TYPE. Как и в

Select b from Book b where TYPE(b) = Book

Вы можете больше узнать о здесь в моем блоге

Эяль

Ответ 4

ORM имитирует Java-модель: если объект является экземпляром другого типа (если экземпляр PersianCat также является экземпляром Cat), любой запрос на Cat должен быть полиморфным (представьте, что вы запрашиваете список и спрашиваете если записи соответствуют instanceof Cat.

Даже решение Bozho несколько нечисто, поскольку столбец "класс" предположительно непрозрачен для вашего отображения спящего режима, хотя я признаю его очень хорошим компромиссом. Вы можете просто получить дискриминатор через простое имя кластера.

Если вы удобно и используете таблицу для каждого класса, вы всегда можете сделать собственный запрос к таблице Cat, чтобы получить идентификаторы, а затем получить записи через спящий режим.

Ответ 5

Посмотрите на BaseQueryReturnFieldsCalculatorGC; он динамически добавляет условие к "where", которое выбирает только, где class= XXX; вы можете дублировать эту логику на HQLQueryTemplate и задать пользователю "isNonPolymorphic".

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