我有以下结构的实体:
@Entity
public Class MyObject {
...
public List<Status> statuses;
...
}
@Entity
public Class Status {
...
public Long creationTime;
public Double range;
@JoinColumn(name = "myObject",
nullable = false,
unique = false,
updatable = false)
@ManyToOne(optional = false)
@NotNull
private MyObject myObject;
...
}
我有n
个MyObject类型的实体,它们可以有m
个状态。所有权位于Status实体的一侧,无法更改。我目前正在尝试过滤大于某个范围的实体。我当前的查询检索每个状态的结果,该状态的范围大于作为参数给出的范围:
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<MyObject> cq = cb.createQuery(MyObject.class);
final Root<MyObject> myObject = cq.from(MyObject.class);
final Root<Status> statuses = cq.from(Status.class);
final Predicate[] predicates = {
cb.equal(myObject.get(MyObject_.id), statuses.get(Status_.myObject).get(MyObject_.id)),
cb.ge(statuses.get(Status_.range), range)
};
cq.select(myObject).where(predicates);
return entityManager.createQuery(cq).getResultList();
期望的是,我只获得MyObject的实体,其中具有范围的最新状态大于等于作为参数给出的状态。我很确定我必须首先对状态列表进行分组并按创建时间排序,但我不确定如何将所有这些组合在一起,尤其是在Criteria API中。
修改 至少我能够创建一个符合我想要的SQL查询:
SELECT * FROM MyObject O INNER JOIN (SELECT * FROM Status WHERE Status.CREATIONTIME IN (SELECT MAX(Status.CREATIONTIME) FROM Status WHERE (Status.RANGE IS NOT NULL AND Status.RANGE >= 30) GROUP BY Status.myObject)) S ON O.ID = S.myObject;
我正在尝试使用Criteria API重建此查询,但我们并不真正知道如何在JOIN中包含嵌入的SELECT。任何帮助将不胜感激!