Java/JPA | Запрос с заданным унаследованным типом

Я создаю запрос в общей таблице "Пример", и у меня есть несколько типов, которые наследуются от этой таблицы "SampleOne", "SampleTwo". Мне нужен запрос вроде:

select s from Sample where s.type = :type

где type будет значением дискриминатора таблицы. Возможно ли это каким-либо образом (и избегать создания запросов, специфичных для сущности, по одному для каждого SampleOne, SampleTwo... и т.д.).

Я был бы очень признателен за любые материалы в этом разделе,

С уважением, Р.

Ответ 1

В JPA 2.0 вы можете использовать выражение TYPE (хотя в настоящее время он не работает с параметрами в Hibernate, см. HHH-5282)

select s from Sample s where TYPE(s) = :type

Аналогичное выражение для спящего режима .class:

select s from Sample s where s.class = :type

Ответ 2

Здесь соответствующий раздел учебника Java EE 6:

Абстрактные объекты

Абстрактный класс может быть объявлено украшая класс @Entity. Абстрактные объекты подобны бетону но не могут быть созданы.

Абстрактные объекты могут быть запрошены только как конкретные объекты. Если абстрактный объект является объектом запроса, запрос работает на всех конкретных подклассы абстрактного объекта:

@Entity
public abstract class Employee {
    @Id
    protected Integer employeeId;
    ...
}
@Entity
public class FullTimeEmployee extends Employee {
    protected Integer salary;
    ...
}
@Entity
public class PartTimeEmployee extends Employee {
    protected Float hourlyWage;
}

Если я прочитаю это правильно, ваш запрос:

select s from Sample where s.type = :type

Должен возвращать только элементы указанного подтипа, если type - столбец дискриминатора, поэтому единственное, что вам осталось сделать - это привести список результатов к вашему запрошенному подтипу.

Ответ 3

Вы все еще должны быть осторожны в Hibernate 4.3.7, потому что проблема с TYPE() по-прежнему остается проблемой, например:

from SpoForeignPilot sfp where TYPE(sfp.partDocument) = :type

Этот запрос не работает, так как он неправильно проверяет тип SpoForeignPilot, а не тип документа.

Вы можете решить эту проблему, выполнив что-то вроде этого:

select sfp from SpoForeignPilot sfp join sfp.partDocument doc where TYPE(doc) = :type

Ответ 4

Сделайте это в вашем хранилище

@Query("SELECT p FROM BaseUserEntity p where p.class=:discriminatorValue")
    public List<BaseUserEntity> findByDiscriminatorValue(@Param("discriminatorValue") String discriminatorValue);

Где BaseUserEntity - ваша родительская сущность