Как создать "экземпляр" -подобного запроса в 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"