Как выполнить неполиморфный HQL-запрос в Hibernate? - PullRequest
28 голосов
/ 19 января 2010

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

Согласно документации запросы Hibernate полиморфны:

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

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

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

Мне известны следующие варианты, и я не нахожу их удовлетворительными:

  1. Ручная фильтрация экземпляров после запроса ИЛИ:
  2. Добавление предложения WHERE вручную в столбец дискриминатора.

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

Заранее спасибо!

Ответы [ 5 ]

25 голосов
/ 19 января 2010

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

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

15 голосов
/ 19 января 2010
SELECT cat FROM Cat cat WHERE cat.class='cat'

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

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

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

11 голосов
/ 14 августа 2010

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

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

Подробнее о можно прочитать здесь в моем блоге

Эяль

1 голос
/ 19 января 2010

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

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

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

0 голосов
/ 01 апреля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...