2012-11-23 47 views
0

我正在使用JPA來管理我的持久層。 我的一個Criteria API引發了一個異常。我重寫了它在JPQL中,它工作得很好,所以我想我錯過了我的標準API版本的東西。 這,我的標準API查詢:JPA標準api查詢失敗,而JPQL通過

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

您可以嘗試下面的代碼。我試圖適應你的代碼,你可以相應地改變。

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)); 
+0

感謝您的。我真的不明白,但我會給它一個 – forhas

+0

我不能真正解釋它,但這似乎鍛鍊得很好。我沒有使用謂詞定義,因爲它們不是類型安全的,但是將它們放入數組解決了它。謝謝 – forhas

+0

@forhas不客氣 –