gpt4 book ai didi

hibernate - JPA + Hibernate count(*) 使用 CriteriaBuilder - 带有 generatedAlias

转载 作者:行者123 更新时间:2023-12-03 06:47:15 24 4
gpt4 key购买 nike

当尝试使用 CriteriaBuilder 创建 count(*) 类型查询时,我遇到以下别名问题。

我应该对下面的代码进行哪些更改才能获取计数?

限制:

  1. 我必须使用 CriteriaBuilder/Query,因为必须根据值动态构建 where 子句。
  2. 我只需要 COUNT,而不是内存中的对象列表。

代码示例片段:

 Class<ReqStatCumulative> entityClass = ReqStatCumulative.class;
@Override
public long getCountForAlertConfig(AlertConfig cfg) {
long count = 0L;
if (null != cfg) {
CriteriaBuilder qb = entityManager.getCriteriaBuilder();

Metamodel model = entityManager.getMetamodel();
EntityType<ReqStatCumulative> reqStatEntType_ = model.entity(entityClass);
CriteriaQuery<ReqStatCumulative> cq = qb.createQuery(entityClass);
Root<ReqStatCumulative> rootReqStatEnt = cq.from(reqStatEntType_);
Path<Long> processTimeSeconds = rootReqStatEnt.<Long> get("processTimeSeconds");
cq.where(qb.and(qb.greaterThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec()),//
qb.lessThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec() + 100))//
);//
findCountByCriteria(entityManager, cq, qb);
log.debug("\n\t#####Alert desc:" + cfg.getDescription());
log.debug("\n\t#####Alert count= " + count);
} else {
// Do nothing
}
return count;
}

public <T> Long findCountByCriteria(EntityManager em, CriteriaQuery<T> cqEntity, CriteriaBuilder qb) {
CriteriaBuilder builder = qb;
CriteriaQuery<Long> cqCount = builder.createQuery(Long.class);
Root<?> entityRoot = cqCount.from(cqEntity.getResultType());
cqCount.select(builder.count(entityRoot));
cqCount.where(cqEntity.getRestriction());
return em.createQuery(cqCount).getSingleResult();
}

日志:我希望在所有 where 子句属性中使用 generatedAlias0,而不是 generatedAlias1。

select count(*) from abc.domain.ReqStatCumulative as **generatedAlias0** where ( **generatedAlias1**.processTimeSeconds>5L ) and ( **generatedAlias1**.processTimeSeconds<200L )

10:48:57.169 [main] DEBUG o.h.h.i.ast.QueryTranslatorImpl - parse() - HQL: select count(*) from abc.domain.ReqStatCumulative as generatedAlias0 where ( generatedAlias1.processTimeSeconds>5L ) and ( generatedAlias1.processTimeSeconds<200L )
10:48:57.169 [main] DEBUG o.h.h.i.ast.QueryTranslatorImpl - --- HQL AST ---
\-[QUERY] Node: 'query'
+-[SELECT_FROM] Node: 'SELECT_FROM'
| +-[FROM] Node: 'from'
| | \-[RANGE] Node: 'RANGE'
| | +-[DOT] Node: '.'
| | | +-[DOT] Node: '.'
| | | | +-[IDENT] Node: 'abc'
| | | | \-[IDENT] Node: 'domain'
| | | \-[IDENT] Node: 'ReqStatCumulative'
| | \-[ALIAS] Node: '**generatedAlias0**'
| \-[SELECT] Node: 'select'
| \-[COUNT] Node: 'count'
| \-[ROW_STAR] Node: '*'
\-[WHERE] Node: 'where'
\-[AND] Node: 'and'
+-[GT] Node: '>'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: '**generatedAlias1**'
| | \-[IDENT] Node: 'processTimeSeconds'
| \-[NUM_LONG] Node: '5L'
\-[LT] Node: '<'
+-[DOT] Node: '.'
| +-[IDENT] Node: '**generatedAlias1**'
| \-[IDENT] Node: 'processTimeSeconds'
\-[NUM_LONG] Node: '200L'

10:48:57.169 [main] DEBUG o.h.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
10:48:57.169 [main] DEBUG o.h.h.i.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]
10:48:57.169 [main] DEBUG o.h.h.internal.ast.tree.FromElement - FromClause{level=1} : erf.domain.ReqStatCumulative (generatedAlias0) -> reqstatcum0_
10:48:57.169 [main] ERROR o.h.hql.internal.ast.ErrorCounter - Invalid path: 'generatedAlias1.processTimeSeconds'
10:48:57.215 [main] ERROR o.h.hql.internal.ast.ErrorCounter - Invalid path: 'generatedAlias1.processTimeSeconds'
org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: 'generatedAlias1.processTimeSeconds'

最佳答案

您的代码失败,因为您对计数和 where 子句使用了不同的 Root 实例:第一个实例(按定义顺序)生成 generatedAlias1 别名,而其他生成 generatedAlias0 。您需要重构代码才能在两个地方使用相同的 Root 实例:

CriteriaQuery<Long> cqCount = builder.createQuery(Long.class);
Root<ReqStatCumulative> entityRoot = cqCount.from(cqEntity.getResultType());
cqCount.select(builder.count(entityRoot));
Path<Long> processTimeSeconds = entityRoot.get("processTimeSeconds");
cqCount.where(qb.and(qb.greaterThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec()),//
qb.lessThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec() + 100))//
);//
return em.createQuery(cqCount).getSingleResult();

关于hibernate - JPA + Hibernate count(*) 使用 CriteriaBuilder - 带有 generatedAlias,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14363634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com