【发布时间】:2014-08-24 21:31:58
【问题描述】:
首先,我是 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);,我得到的每个项目的数量是项目数量的两倍。 (我的意思是,一共应该有8个Item,现在我每个得到8次,所以总共有64条记录)
这种行为的原因是什么,我应该如何解决?
【问题讨论】:
标签: java hibernate jpa criteria