首先,我是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个记录)
这种行为的原因是什么,我应该如何解决?
答案 0 :(得分:0)
有点令人尴尬:错误地增加了query.from(Item.class);
。