我正在使用JPA来管理我的持久层。 我的一个Criteria API会引发异常。我在JPQL中重新编写它并且它工作得很好所以我想我错过了我的标准api版本的东西。 这是我的标准api查询:
public FoodItemTagsOverrideRule findByFoodItemIdAndType(long foodItemId, RuleTypes ruleType) {
CriteriaQuery<Rule> c = getCriteriaQuery();
Root<Rule> rule =
c.from(Rule.class);
Predicate foodItemIdCondition =
cb.equal(rule.get(Rule_.foodItemId), foodItemId);
Predicate typeCondition =
cb.equal(rule.get(Rule_.ruleType),
ruleType.toString());
c.where(foodItemIdCondition, typeCondition);
TypedQuery<Rule> q =
entityManager.createQuery(c);
List<Rule> result = q.getResultList();
if (result.isEmpty()) {
return null;
}
return result.get(0);
}
运行得很好的JPQL版本:
public Rule findByFoodItemIdAndType(long foodItemId, RuleTypes ruleType) {
TypedQuery<Rule> query = getEntityManager().createQuery(
"SELECT rule " + "FROM " + Rule.class.getSimpleName() + " rule " + "WHERE rule.foodItemId = :foodItemId "
+ "AND rule.ruleType = :ruleType", Rule.class);
query.setParameter("foodItemId", foodItemId);
query.setParameter("ruleType", ruleType.toString());
List<Rule> result = query.getResultList();
if (result.isEmpty()) {
return null;
}
return result.get(0);
}
你能看到有什么区别吗?我是否在标准api查询中出错?
Thakns!
答案 0 :(得分:0)
您可以尝试以下代码。我试图适应你的代码,你可以相应地改变。
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery();
Root<Rule> rule = cq.from(Rule.class);
List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(qb.equal(rule.get("foodItemId"), foodItemId));
predicates.add(qb.equal(rule.get("ruleType"), ruleType));
cq.select(rule).where(predicates.toArray(new Predicate[]{}));
em.createQuery(cq).getResultList();
编辑:对于类型安全的谓词定义
predicates.add(qb.equal(rule.get(Rule_.foodItemId), foodItemId));
predicates.add(qb.equal(rule.get(Rule_.ruleType), ruleType));