通过检查已过滤的childen子集来检索实体

时间:2015-12-01 10:58:55

标签: sql group-by criteria-api

我有以下结构的实体:

@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。任何帮助将不胜感激!

0 个答案:

没有答案