JPA Criteria动态谓词创建

时间:2014-08-24 21:31:59

标签: java hibernate jpa criteria

首先,我是JPA的新手,特别是对于标准API,所以它可能是我做错的基础。

我正在尝试从数据库中选择一些项目。我想实现分页,所以将来我需要在一个返回对象数量的方法中重用谓词。现在,我想将谓词的构建与实际的查询执行分开。我提出了以下两种方法:

    private Predicate assemblePredicateBasedOnParameters(Map<String, String> parameterMap, Root<Item> item){

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();

    Predicate predicate = cb.conjunction();

    for(String parameter : parameterMap.keySet()){

        String value = parameterMap.get(parameter);

        if(parameter.equals(FilteringKeyword.NAME.toString()))
        {
            Predicate newPredicate = cb.like(item.<String>get(FilteringKeyword.NAME.toString()), "%"+value+"%");
            predicate = cb.and(predicate, newPredicate);
        }
        else if(parameter.equals(FilteringKeyword.DESCRIPTION.toString())){
            Predicate newPredicate = cb.like(item.<String>get(FilteringKeyword.DESCRIPTION.toString()), "%"+value+"%"); 
            predicate = cb.and(predicate, newPredicate);
        }
        else if(parameter.equals(FilteringKeyword.MINPRICE.toString())){
            Predicate newPredicate = cb.ge(item.<Integer>get("startingPrice"), Integer.parseInt(value));    
            predicate = cb.and(predicate, newPredicate);
        }
        else if(parameter.equals(FilteringKeyword.MAXPRICE.toString()) && Integer.parseInt(value)>0){
            Predicate newPredicate = cb.le(item.<Integer>get("startingPrice"), Integer.parseInt(value));    
            predicate = cb.and(predicate, newPredicate);
        }


    }

    return predicate;

}

@Override
public List<Item> getItems(Map<String, String> parameterMap, int from, int to) {

    CriteriaQuery<Item> query = entityManager.getCriteriaBuilder().createQuery(Item.class);

    query.from(Item.class);

    Root<Item> item = query.from(Item.class);

    Predicate predicate = assemblePredicateBasedOnParameters(parameterMap, item);

    query.where(predicate);
    //query.select(item);

    TypedQuery<Item> q = entityManager.createQuery(query);
    List<Item> result = q.getResultList();

    System.out.println("results of query: "+result);

    return result;

}

当我像上面那样运行它时(查询了query.select),我收到以下错误:java.lang.IllegalStateException: No explicit selection and an implicit one cold not be determined at org.hibernate.jpa.criteria.CriteriaQueryImpl.validate(CriteriaQueryImpl.java:279)

这很奇怪,因为当整个事情在一种方法中时,它没有选择后退。

但如果我实际上打电话给query.select(item);,我会得到每个项目的次数和项目数量。 (我的意思是,总共应该有八个项目,现在我每次都得到八个,所以总共有64个记录)

这种行为的原因是什么,我应该如何解决?

1 个答案:

答案 0 :(得分:0)

有点令人尴尬:错误地增加了query.from(Item.class);

相关问题