0

I'm using JPA to manage my persistency layer. One of my my Criteria API throws an exception. I re-wrote it in JPQL and it works just fine so I guess I missed something in my criteria api version. Here it is, my criteria api query:

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

The JPQL version that works just fine:

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

Can you see a difference there? Did I put something wrong in the criteria api query?

Thakns!

forhas
  • 11,551
  • 21
  • 77
  • 111

1 Answers1

0

You can try the below code. I tried to fit to your code, you can alter accordingly.

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

Edit : For type-safe predicate definition

predicates.add(qb.equal(rule.get(Rule_.foodItemId), foodItemId));
predicates.add(qb.equal(rule.get(Rule_.ruleType), ruleType));
Nayan Wadekar
  • 11,444
  • 4
  • 50
  • 73
  • Thanks for that. I don't really see the difference but I'll give it a shot – forhas Nov 23 '12 at 13:15
  • I can't really explain it but this seem to workout just fine. I did not use your predicates definition since they are not type safe, but putting them in an array solved it. Thanks – forhas Nov 25 '12 at 10:05