Как создать "экземпляр" -подобного запроса в JPA 2.0?

Скажем, у нас есть абстрактный @Entity Animal и несколько классов сущностей, которые расширяют Animal, включая Dog, Cat, Monkey и Bat.

Как фильтровать результаты на основе расширяющегося класса сущностей?

Пример: Есть флажки, в которых пользователь может выбрать, какие объекты будут извлекаться.

[ ] Dog
[X] Cat
[X] Monkey
[ ] Bat

Теперь я хочу получить объекты с запросом (Named), определенным в классе Animal. Какие параметры запроса можно поместить в запрос, чтобы возвращались только объекты Cat и Monkey?

Ответ 1

Я не уверен, что это поддерживается JPA, но способ сделать это в Hibernate, независимо от стратегии наследования, и, таким образом, даже если у вас нет дискриминатора (или не отображал его как свойство ) заключается в использовании неявного свойства class:

String jpql = "select a from Animal a where a.class in (:classes)";
Query q = em.createQuery(jpql).setParameter("classes", 
                                            Arrays.asList(Cat.class, Monkey.class));

EDIT:

Я просто нашел это возможным в JPA2 с помощью оператора TYPE:

String jpql = "SELECT a FROM Animal a WHERE TYPE(a) IN :classes";
Query q = em.createQuery(jpql).setParameter("classes", 
                                            Arrays.asList(Cat.class, Monkey.class));

Ответ 2

Вы можете использовать столбец и значение дискриминатора для поиска только определенных подтипов данного типа. По умолчанию имя столбца дискриминатора - это DTYPE в JPA, тип - String, а значение - это имя класса. Однако вы можете переопределить это, добавив аннотацию уровня класса @DiscriminatorColumn(name="KIND", discriminatorType=DiscriminatorType.INTEGER) (для имени и типа столбца дискриминатора) и @DiscriminatorValue("1") (для конкретного значения дискриминатора для определенного класса). Затем вы можете использовать это в предложении WHERE запроса yoru JPQL только для получения определенных подтипов, например: WHERE DTYPE="Dog" OR DTYPE="Cat"