2012-02-08 12 views
1

私はJPAプロバイダとしてEclipseLinkを使用しています。JPA multiselect

オンラインで1つのCriteriaクエリを使用して特定のIDsに対応するすべての名前を取得するクエリを作成したいとします。

Root<UserAccount> root = criteria.from(UserAccount.class); 
List<Selection<?>> select = new ArrayList<Selection<?>>(); 
    for (MyElement element : list) { 
    Expression<String> firstName = root.get("firstName"); 
    Expression<String> lastName = root.get("lastName"); 
    Expression<Integer> id = root.get("id"); 
    select.add(criteria 
       .multiselect(
         firstName.alias(element.getId() + "_" 
           + element.getEntity() + "f"), 
         lastName.alias(element.getId() + "_" 
           + element.getEntity() + "l")) 
       .where(criteriaBuilder.equal(id, element.getAuthorId())) 
       .from(UserAccount.class) 
       .alias(element.getId() + "_" + element.getEntity())); 
} 
criteria.multiselect(select); 
TypedQuery<Tuple> q = em.createQuery(criteria); 
for (Tuple t : q.getResultList()) { 
     for (OverviewEntity element : list) { 
System.out.println("////" 
         + t.get(element.getId().toString() + "_"+element.getEntity()+"f", 
           String.class)); 

element.getId() + "_" + element.getEntity() + "f"私は一意のエイリアスを作成します。

問題は、私が得るのはnullです。どうして? 1つのクエリでこれらをすべて取得する必要があります(時間がかかることはありません)。

+0

なぜあなたは(ユニーク)のエイリアスを作成したいですか? element.getEntity()とは何ですか? – perissf

+0

@perissf結果が得られたら、すべての結果がどこに当てはまるかを知りたいと考えています。 'ID'だけでは不十分です。' @ Transient'(データベースにはない)情報がいくつかあります。 – Dragos

+0

このデザインは非常に複雑です。私は、与えられたセットのIDを持つすべてのUserAccountレコードを返すプレーンなクエリを書くでしょう。 resultListはPersistenceContextにアタッチされます。あなたは何の努力もせずにTransientプロパティを取得することができます。エイリアスを使用する必要はありません。 – perissf

答えて

2

コメントで示唆したように、私はCriteriaBuilderやメタモデルを使用して

List<Integer> myList = ....; // place here your ids 
TypedQuery<UserAccount> q = em.createQuery("select u from UserAccount u where u.id in (:myList)", UserAccount.class); 

または同等のクエリのような簡単な解決策のために行くだろうが:

Root<UserAccount> root = q.from(UserAccount.class); 
Expression<Integer> exp = root.get(UserAccount_.id); 
Predicate predicate = exp.in(myList); 
criteria.where(predicate); 

​​が返さが接続されているエンティティインスタンスが含まれていますPersistenceContextにこれは、努力なしでTransientのプロパティを取得できることを意味します。

パフォーマンスに関しては、返されるリストのサイズが非常に大きい場合や頻繁にこのクエリを繰り返す必要があるような極端な状況でのみ顕著な違いが生じる場合があります。しかし、これには深い分析が必要です。

8

あなたのコードは非常に混乱しており複雑です。

Select u.firstName, u.lastName, u.id from UserAccount u where u.id in (:ids) 

が動作するように思われるJPQL、これは基準で

Root<UserAccount> root = criteria.from(UserAccount.class); 
criteria.multiselect(root.get("firstName"), root.get("lastName"), root.get("id")); 
criteria.where(criteriaBuilder.in(root.get("id"), criteriaBuilder.parameter("ids")); 
+0

提供されたコードをありがとう。それでもなお、問題はこれです:一つの '要素'は 'A'型か 'B型'です。どのような型であるかを知ることができます: 'element.getEntity()'。私が結果を得るとき、返された 'id'とそれに対応する' firstName'と 'lastName'が' A'か 'B'に属するかどうかを知るべきです。それは単に文字列をデータベースから取得するのではなく、問題です。 – Dragos