2016-03-26 23 views
1

新しい問題があります。クライアント要求から述語を生成するコードをいくつか作成しました。これは、一部の初期化されます。Jpa基準数

criteriaBuilder = entityManager.getCriteriaBuilder(); 
criteriaQuery = criteriaBuilder.createQuery(classEntity); 
root = criteriaQuery.from(classEntity); 

私はそれは素晴らしい仕事リストエンティティを取得したいときは:

criteriaQuery.select(root).where(predicate); 
entityManager.createQuery(criteriaQuery).getResultList(); 

をしかし、私はカウントエンティティを取得したいとき:

CriteriaQuery<Long> cq = criteriaBuilder.createQuery(Long.class); 
cq.select(criteriaBuilder.count(root)).where(predicate); 
System.err.println("eee : " +entityManager.createQuery(cq).getSingleResult()); 

それは例外で落ちる

java.lang.IllegalArgumentException: Error occurred validating the Criteria Caused by: java.lang.IllegalStateException: No criteria query roots were specified

private Path parseField(String field) { 
    Path path = null; 

    if (field.contains(".")) { 

     String [] split = field.split("\\."); 
     Join join = root.join(split[0],JoinType.INNER); 

     for (int i =1; i < split.length-1; i++) { 
      join = join.join(split[i],JoinType.INNER); 
     } 

     path = join.get(split[split.length-1]); 

    } else { 
     path = root.get(field); 
    } 
    return path; 
} 

私は例外

org.hibernate.hql.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.(someFieldName)' 
+0

どのようにparseFieldを使用していますか? – Amalgovinus

答えて

1
で失敗します

cq.select(criteriaBuilder.count(root)).where(previousPredicate); 

cq.select(criteriaBuilder.count(cq.from(classEntity))).where(previousPredicate); 

に置き換える場合:

は、おそらく私は、動的に加入すること根が発生し、言わなければなりませんそれはすべてが私のために正常に動作します:

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Long> q = cb.createQuery(Long.class); 
Root<A> r = q.from(A.class); 
MapJoin<A, String, String> m = r.joinMap("metadata"); 
q.select(cb.count(r)).where(cb.equal(m.key(), "A")); 
Long rs = em.createQuery(q).getSingleResult(); 

だから、それはあなたがMCVEずに間違っているのかを見るのは難しいです。

+0

私は問題を解決しました。述語には、他のCriteriaQueryによるmetaInfoが含まれています。私はクラスのアーキテクチャを変更し、私は他のクエリの2つの述語を生成していました。助けてくれてありがとう! –

関連する問題