where 子句中的子查询,带有 CriteriaQuery 以获得更大和等于运算符

问题描述 投票:0回答:1

我有以下 SQL 查询,我想为其编写 CriteriaQuery

select * from EntityA ea where ea.lastUpdateTS >= (select creationDate from EntityB where status='PUBLISHED' order by creationDate DESC limit 1) 

java.time.Instant
对象中的最后一次更新。我尝试编写以下 CriteriaQuery 但它不起作用,而且我无法找到子查询如何应用于根查询

        //Main query
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<EntityA> rootCriteriaQuery = criteriaBuilder.createQuery(EntityA.class);
        Root<EntityA> baseEntityRoot = rootCriteriaQuery.from(EntityA.class);
        Path<Object> path = baseEntityRoot.get("lastUpdateTS");

        //Sub query
        Subquery<EntityB> subQuery = rootCriteriaQuery.subquery(EntityB.class);
        Root<EntityB> subRoot = subQuery.from(EntityB.class);
        subQuery.select(subRoot.get("creationDate"));
        Predicate publishedPredicate = criteriaBuilder.equal(instantRoot.get("status"), "PUBLISHED");
        instantSubQuery.where(publishedPredicate);

在此之后,我想编写下面的代码

rootCriteriaQuery.where(criteriaBuilder.greaterThanOrEqualTo(path, instantSubQuery));

但是编译器显示错误。任何人都可以建议如何使用子查询创建更大和等于运算符。

java jpa subquery hibernate-criteria criteria-api
1个回答
0
投票

根查询的路径(路径变量)和子查询结果(instantSubQuery)类型不匹配是问题所在。子查询不会返回creationDate字段,因此greaterThanOrEqualTo函数需要兼容的类型。

您需要子查询选择EntityB 中的creationDate 字段。 然后将 criteriaBuilder.greaterThanOrEqualTo 应用于子查询的结果。 像那样:

// Main query
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<EntityA> rootCriteriaQuery = criteriaBuilder.createQuery(EntityA.class);
Root<EntityA> baseEntityRoot = rootCriteriaQuery.from(EntityA.class);
Path<Instant> path = baseEntityRoot.get("lastUpdateTS");

// Subquery
Subquery<Instant> subQuery = rootCriteriaQuery.subquery(Instant.class);
Root<EntityB> subRoot = subQuery.from(EntityB.class);
subQuery.select(subRoot.get("creationDate")); // Select creationDate from EntityB
Predicate publishedPredicate = criteriaBuilder.equal(subRoot.get("status"), "PUBLISHED");
subQuery.where(publishedPredicate);
subQuery.orderBy(criteriaBuilder.desc(subRoot.get("creationDate")));
subQuery.select(subRoot.get("creationDate")).distinct(true);

// Limit to 1 result by selecting the top-most creationDate
subQuery = subQuery.orderBy(criteriaBuilder.desc(subRoot.get("creationDate")));
subQuery.select(subRoot.get("creationDate"));

// Apply subquery in main query
rootCriteriaQuery.where(criteriaBuilder.greaterThanOrEqualTo(path, subQuery));

// Execute the query
TypedQuery<EntityA> query = entityManager.createQuery(rootCriteriaQuery);
List<EntityA> results = query.getResultList();
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.