2013-08-16 6 views
11

を制限私は、アプリケーションのすべてのデータを返すの基準を持っているが、基本的に、必要です。Hibernateの基準:その後、個別のエンティティと

Criteria criteria = session.createCriteria(Client.class); 
criteria.createAlias("address", "address"); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

問題は関係クライアント/アドレスが双方向であるということです:クライアント上の一つのアドレスを持っており、 1つのアドレスが複数のクライアントに属している可能性があります。

「単一の」クライアントオブジェクトは、そのテーブルに表示されているクライアント数に基づいて取得したいと考えています。

最初にsetFirstResult/setMaxResultsが実行されるため、すでに適用されている制限内で重複したクライアントが取得されています。 (グループレベルではないアプリケーションレベルが使用された)後、hibernateは複製されたクライアントのリッジを取得して、setMaxResultsで指定された最大数よりも少ないクライアントで終了します。

(投影グループ)は、クライアント/アドレスで必要なすべての列を返さず、クエリがグループ化しているグループのみをグループ化することはできません。

(要約すると、1ページに100の結果がありますが、重複を破棄した後、100の代わりに98の結果が得られます)。これは、リミット:LIMIT0,100が適用されるためです。 )

答えて

7

はこれを解決します

criteria.setFetchMode("address.clients", FetchMode.SELECT); 

それはなされるべき問題を引き起こすことに参加防ぎます。

もちろん、xml構成ファイルからfetch = "join"を削除することはできますが、この解決策はBeanが検索される可能性のある他の場所には影響しません。

+0

FetchMode.SELECTは私のために修正しました - この場合、他のモードは動作しません。 –

+0

FetchMode.SELECTは素晴らしいです...何らかの理由でそれを強制的に取得することを除けば、 フェッチされているエンティティのpkに "distinct"を実行するだけで休止状態を知らせる方法はありませんか? ??これは最も明白な些細なもののように思えますし、いつものように、休止状態は人生を非常に複雑にしてくれます。 – Marc

+0

ところで、HQLでこれを行うのは、それが聞こえるほど些細なことです。あなたはあなたの質問に「distinct」という言葉を追加するだけです。なぜこれがCriteria APIを使用して痛いほど厄介なのかは、私の外にあります。 OOデータベースの使用はまだ開始できますか? – Marc

4

idに基づいてクライアントを探している場合は、次のようになります。あなたの基準に基づいて、常に1つのクライアントを返すので、maxとinitのサイズは必要ありません。

Criteria criteria = getSession().createCriteria(Client.class); 
criteria .add(Restrictions.eq("id", yourClientId); 
criteria.createAlias("address", "address"); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

次のようにIDを基にして住所を検索している場合。

Criteria criteria = getSession().createCriteria(Client.class); 
criteria.createAlias("address", "address"); 
criteria .add(Restrictions.eq("address.id", yourAddressId); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 
+3

お返事ありがとうございますが、私はすべてのクライアントを探していました。それらをページの応答として返しました。この問題は、100個の結果を返すページよりも、ページをグループ化した後の返り値が少なくなります(DISTINCT_ROOT_ENTITY)。そのグループ化は限界の前に起こるはずです... – kandan

+0

2番目のブロックは、彼の質問で@kandanによって投稿された行の数が少なくなる可能性があります。 –

0

私が正しくあなたの関係を理解し​​ていれば、あなたは住所や各クライアントエンティティクラスの一つのアドレスに、クライアントのリストを持っています。 だから、あなただけのクライアントのリストをしたい場合は、大したことは何でしょう、あなただけなぜあなたはエイリアスを作成し、distinct_root_entityを使用している

Criteria criteria = session.createCriteria(Client.class); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

でそれらを得ることができませんか?そのアドレスを取得する必要がある場合は、DAOまたはServiceImplでアクセスするときに、Hibernateはそれをあなたに遅れて取得します。

私が間違っている場合は私を修正してください。それは「アシシュThukral」の次の行によってリンクされたスレッドの中で指摘されたよう

+0

ありがとう。エイリアスを作成して、hibernateがクエリで他のデータを取得するようにしています。たとえば、フィルタを使用してクライアントをフィルタリングしている可能性があります(フィルタが付いたページテーブルです)。だから私は必要なすべてのデータを取得する:アドレスを持つクライアント。問題は、アドレスでは、そのアドレスを持つクライアントのセットが来ると私はresulttransformerが彼らのIDでクライアントを統一する必要があります。おそらく、アノテーションを変更することなく、クラス/テーブルの特定のカラムを取得/結合しないように、デフォルトで定義されている(遅延していないかどうかに関わらず)他のフィールドに対しても行うことができます。 – kandan

+1

あなたはこれを探していると思います。 http://stackoverflow.com/questions/5567754/hibernate-criteria-n1-issue-with-maxresults?rq=1 –

+0

はい、ありがとうございます。 – kandan

関連する問題