Java / JPA |Запрос с указанным унаследованным типом - PullRequest
11 голосов
/ 03 февраля 2011

Я строю запрос к общей таблице «Образец», и у меня есть несколько типов, которые наследуются от этой таблицы «Образец», «Образец два» Мне нужен запрос как:

select s from Sample where s.type = :type

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

Буду очень признателен за любой вклад в эту тему,

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

Ответы [ 3 ]

15 голосов
/ 03 февраля 2011

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

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

Аналогичное для Hibernate выражение: .class:

select s from Sample s where s.class = :type
4 голосов
/ 03 февраля 2011

Вот соответствующий соответствующий раздел учебника по 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 является столбцом дискриминатора, поэтому единственное, что вам остается сделать, - привести список результатов к запрошенному вами подтипу.

2 голосов
/ 01 августа 2016

Вы все равно должны быть осторожны в 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
...