我有以下 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));
但是编译器显示错误。任何人都可以建议如何使用子查询创建更大和等于运算符。
根查询的路径(路径变量)和子查询结果(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();