计数JPA和无效路径

计数JPA和无效路径,jpa,Jpa,在检查堆栈溢出后,我找到了以下解决计数问题的方法。我的要求是获取匹配行的总数,并返回前十行以进行分页 CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<T> cq = cb.createQuery(clazz); CriteriaQuery<Long> counterCq = cb.createQuery(Long.class); counterCq.select(cb.count(counterCq.

在检查堆栈溢出后,我找到了以下解决计数问题的方法。我的要求是获取匹配行的总数,并返回前十行以进行分页

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(clazz);
CriteriaQuery<Long> counterCq = cb.createQuery(Long.class);
counterCq.select(cb.count(counterCq.from(clazz)));
Predicate predicate= null;
Predicate predicate1 = null;
Root<T> root = cq.from(clazz);
for (Map.Entry<String, String> e : filters.entrySet()){
    predicate = cb.and(cb.like(root.<String>get(e.getKey()), e.getValue()+ "%"));
}
if(predicate != null){
    cq.where(predicate);
    counterCq.where(predicate);
}
int pn = ( em.createQuery(counterCq).getSingleResult()).intValue();
logger.debug("number of pages is {}", pn);
setRowCount(pn);

if(sortField !=null && !sortField.trim().equals("")){
    if(sortOrder == SortOrder.DESCENDING){
        cq.orderBy(cb.desc(root.get(sortField)));
    } else{
        cq.orderBy(cb.asc(root.get(sortField)));
    }
}

Query q = em.createQuery(cq);
q.setFirstResult(first);
q.setMaxResults(first+ps);
List<T> cats= (List<T>)q.getResultList();
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(clazz);
CriteriaQuery counterCq=cb.createQuery(Long.class);
计数器CQ.select(cb.count(计数器CQ.from(clazz));
谓词=null;
谓词谓词1=null;
根根=cq.from(clazz);
对于(Map.Entry e:filters.entrySet()){
谓词=cb.and(cb.like(root.get(e.getKey()),e.getValue()+“%”);
}
if(谓词!=null){
cq.where(谓词);
counterCq.where(谓词);
}
int pn=(em.createQuery(counterCq.getSingleResult()).intValue();
debug(“页数为{}”,pn);
设置行数(pn);
if(sortField!=null&&!sortField.trim().equals(“”){
if(sortOrder==sortOrder.DESCENDING){
orderBy(cb.desc(root.get(sortField));
}否则{
orderBy(cb.asc(root.get(sortField));
}
}
查询q=em.createQuery(cq);
q、 setFirstResult(第一);
q、 setMaxResults(第一个+ps);
List cats=(List)q.getResultList();
此代码段使hibernate无法运行

java.lang.IllegalArgumentException:org.hibernate.hql.ast.QuerySyntaxException:无效路径:“generatedAlias1.title”[选择媒体中的计数(generatedAlias0)作为generatedAlias0,其中generatedAlias1.title类似于:param0]

似乎
cq.from(clazz)
无法应用于其他查询。
现在我的问题是:有没有办法在两个查询中使用相同的谓词

您的谓词列表没有正确组合。必须将“and”谓词合并到一个表达式中。我还更喜欢在执行select之前构建谓词,以提高可读性

下面是代码的重构,以获得正确的结果:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(clazz);
Root<T> root = cq.from(clazz);

// build predicate list - conjuction starts us with an empty 'and' predicate
Predicate predicate = cb.conjunction();
for (Map.Entry<String, String> e : filters.entrySet()) {
    predicate = cb.and(predicate, cb.like(root.get(e.getKey()), e.getValue() + "%"));
}

// query total count
CriteriaQuery<Long> counterCq = cb.createQuery(Long.class);
counterCq.select(cb.count(root)).where(predicate);

int pn = (em.createQuery(counterCq).getSingleResult()).intValue();
logger.debug("number of pages is {}", pn);
setRowCount(pn);

// query results
cq.select(root).where(predicate);

if(sortField !=null && !sortField.trim().equals("")) {
    if(sortOrder == SortOrder.DESCENDING) {
        cq.orderBy(cb.desc(root.get(sortField)));
    }
    else {
        cq.orderBy(cb.asc(root.get(sortField)));
    }
}

TypedQuery<T> q = em.createQuery(cq);
q.setFirstResult(first);
q.setMaxResults(first+ps);
List<T> list = q.getResultList();
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(clazz);
根根=cq.from(clazz);
//构建谓词列表-conjuction以空的“and”谓词开始
谓词=cb.conjunction();
对于(Map.Entry e:filters.entrySet()){
谓词=cb.and(谓词,cb.like(root.get(e.getKey()),e.getValue()+“%”);
}
//查询总计数
CriteriaQuery counterCq=cb.createQuery(Long.class);
counterCq.select(cb.count(root)).where(谓词);
int pn=(em.createQuery(counterCq.getSingleResult()).intValue();
debug(“页数为{}”,pn);
设置行数(pn);
//查询结果
选择(根).where(谓词);
if(sortField!=null&&!sortField.trim().equals(“”){
if(sortOrder==sortOrder.DESCENDING){
orderBy(cb.desc(root.get(sortField));
}
否则{
orderBy(cb.asc(root.get(sortField));
}
}
TypedQuery q=em.createQuery(cq);
q、 setFirstResult(第一);
q、 setMaxResults(第一个+ps);
List List=q.getResultList();