QueryDSL Inheritance: подтип в предложении where
Я пытаюсь создать запрос, который должен возвращать подтипы (список InternalTask и ExternalTask). Это прекрасно работает, но я хочу добавить предложение where в запрос для одного из подтипов. Я пробовал следующее:
Объекты:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TASK_TYPE")
public abstract class Task {
...
}
@Entity
@DiscriminatorValue("INTERNAL")
public class InternalTask extends Task {
...
private Employee employee;
...
}
@Entity
@DiscriminatorValue("EXTERNAL")
public class ExternalTask extends Task {
...
}
Функция:
public List<? extends Task> findTasks(TaskSearch taskSearch) {
JPAQuery query = new JPAQuery(entityManager);
QTask task = QTask.task;
BooleanBuilder where = new BooleanBuilder();
if (taskSearch.getEmployee() != null) {
where.and(task.instanceOf(InternalTask.class).and(task.as(QInternalTask.class).employee.eq(taskSearch.getEmployee())));
}
query.from(task).where(where).orderBy(task.deadline.asc());
return query.list(task);
}
Ошибка:
An error occurred while parsing the query filter "select task_
from Task task_
where (type(task_) = ?1 and task_.employee = ?2)
order by task_.deadline asc". Error message: No field named "employee" in "Task". Did you mean "deadline"? Expected one of the available field names in "com.exampe.Task": "[deadline]".
Как вы можете видеть, он преобразуется в объект выбора Task, который не знает подтипа InternalTask. Есть ли способ выполнить предложение where для подтипа?
1 ответ
Я нашел решение, добавив подзапрос:
public List<? extends Task> findTasks(TaskSearch taskSearch) {
JPAQuery query = new JPAQuery(entityManager);
QTask task = QTask.task;
QInternalTask internalTask = QInternalTask.internaltask;
BooleanBuilder where = new BooleanBuilder();
if (taskSearch.getEmployee() != null) {
JPASubQuery from = new JPASubQuery().from(internalTask)
.where(internalTask.employee.eq(taskSearch.getEmployee()).and(internalTask.id.eq(task.id)));
where.and(from.exists());
}
query.from(task).where(where).orderBy(task.deadline.asc());
return query.list(task);
}