我的任务是将动态搜索查询从sql迁移到jpa criteria api。查询返回有关从各种关联实体收集的任务的信息。在简化的形式中,类看起来像这样:
@Entity
@Table(name = "TASKS")
public class Task {
private AbstractPayload payload;
}
@Entity
@Table(name = "TASK_PAYLOAD")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING)
public abstract class AbstractPayload {
// Id and other stuff
}
@Entity(name = "PayloadSubtype")
@DiscriminatorValue("2")
public class PayloadSubtype {
@Column(name = "MOST_RECENT_RESPONSE_DATE")
@Temporal(TemporalType.TIMESTAMP)
private Date lastResponseDate;
}
查询应该只发出一个语句。我的第一个方法看起来像这样:
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> taskQuery = criteriaBuilder.createTupleQuery();
Root<Task> task = taskQuery.from(Task.class);
Join<Task, AbstractPayload> payload = task.join(Task_.payload);
CriteriaQuery<Tuple> multiselect = taskQuery.multiselect(
payload.get(PayloadSubtype_.lastResponseDate);
在最后一行,payload.get引发编译错误: “Path类型中的方法get(SingularAttribute)不适用于参数(SingularAttribute)”
可以理解,因为AbstractPayload至少从OO的角度来看没有属性lastResponseDate。
我发现了一些建议使用特定于子类型的子查询的问题和答案。但问题是子查询不能与元组查询一起使用。
我尝试过这样的东西来构建一个子查询:
Subquery<PayloadSubtype> specificSubquery = taskQuery.subquery(PayloadSubtype.class);
Root<PayloadSubtype> payloadSubtype = specificSubquery.from(PayloadSubtype.class);
payloadSubtype.alias("payloadSubtype");
Root<Task> taskCorrelation = specificSubquery.correlate(task);
Path<AbstractPayload> taskPayload = taskCorrelation.get(Task_.payload);
Path<Long> payloadId = reviewNonResponderPayload.get(AbstractPayload_.id);
reviewNonResponderSubquery
.select(payloadSubtype)
.where(criteriaBuilder.equal(taskPayload, payloadId));
CriteriaQuery<Tuple> multiselect = taskQuery
.multiselect(
payloadSubtype.get(PayloadSubtype_.lastResponseDate));
此代码编译,但在运行时抛出异常:无效路径:'payloadSubtype.lastResponseDate'
或者如果我省略别名:无效路径:'generatedAlias3.lastResponseDate'
有人知道如何通过JPA Criteria完成这项工作,或者这根本不可能完成吗?