计算JPA和无效路径

时间:2011-10-24 18:52:43

标签: jpa

在讨论Stack Overflow后,我找到了以下解决问题的方法。我的要求是获取匹配行的总数,并返回前十个用于分页的目的。

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();

此代码片段通过

进行休眠
  

java.lang.IllegalArgumentException:org.hibernate.hql.ast.QuerySyntaxException:无效路径:'generatedAlias1.title'[从媒体中选择count(generatedAlias0)as generatedAlias0 where generatedAlias1.title like:param0]

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

1 个答案:

答案 0 :(得分:4)

您的谓词列表未正确汇编。你必须将'和'谓词放在一起作为一个表达式。我还喜欢在执行选择之前构建我的谓词以获得更好的可读性。

这是您的代码的重构,以实现正确的结果:

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();