2009-07-07 9 views
1

私は従来のiBatisの実装をHibernateに変換しています。下位互換性のために、コレクション自体ではなくオブジェクトのコレクションの数を表示する必要があります。元のクエリは次のとおりです。このクエリをHibernateで実装する方法は?

select A.*, (select count(*) from B where B.A_id = A.id) as B_count from A; 

b_countが応答に表示されます。私は、クエリ結果ごとにBのレイジーローディングAのコレクションを使用せずに同じことができるようにしたいと思います。

アイデアや提案はありますか?

+0

私のオフィスの同僚は@Formulaアノテーションを推奨しました。私は答えとして解決策を書くつもりです。 –

答えて

2

最善の方法は、私のBCOUNTのゲッターとセッターにマッピングされ、Hibernateの式を使用しているように見えます属性クラスAに私のコード:この方法について

public class A { 
    // ... 
    private long bCount; 

    // ... 

    @Formula("(select count(*) from B where B.A_id = id") 
    public long getBCount() { 
     return this.bCount; 
    } 

    public void setBCount(long bCount) { 
     this.bCount = bCount; 
    } 
} 

素晴らしいところは、最初のオブジェクトを水和するためにフェッチし、コレクションクエリのresulのための1つの+ Nクエリにはなりません数が同じで返されていることですts!

+0

私はこれが可能であることを知らなかった。コードベースには、これで恩恵を受けるいくつかの場所があることはわかっています。 – Jesse

0

投影を使用できます。

行数の構文は以下の通りです:

Criteria crit = session.createCriteria(B.class); 
    crit.setProjection(Projections.rowCount()); 
    List results = crit.list(); 

編集:再読み込みした後、私はこれがあなたが求めているものではないかもしれないと思う....

+0

私が探していたものではありませんでしたが、それでも感謝しています! –

0

Hibernateフィルタは、クエリ結果に追加の制限を適用するために使用されます(たとえば、where句の一部として考える)ので、あなたが望むことはできません。

A)あなたは熱心にあなたのAのためのBsのコレクションを取得することができます:

from A a left join fetch a.Bs b
その場合、あなたが結果に重複を得ることができますように、複数の返すクエリにあることに注意してくださいあなたはここに2つのオプションがありますリスト(例えば、2つのAsがあり、それぞれに3つのBsがある場合、6つの結果が戻されます)。ユニークさを保証するためにセットでラップします。

B)あなたは次の操作を行うことができ、あなたがAのための適切なコンストラクタを持っていると仮定すると:

 
select new A(a.field1, a.field2, ... a.fieldN, count(*) as B_count) 
    from A a left join a.Bs b 
    group by a.field1, a.field2, ... a.fieldN 

関連する問題