2011-06-23 13 views
1

フェッチ参加します親モデルの「子」モデルのセット)。休止クライテリアAPIの結果は、私が2つの単純なモデルを持っている

'John'に2人の子供がいる場合、上記のクエリの結果は、1つのクエリを実行することで、2人の子供を持つ2人の親(同じ参照)のリストを私に与えます。

私は以下のような基準APIを経由して同じことを達成しようとしています:上記のコードでは

Criteria c = session.createCriteria(Parent.class); 
c.setFetchMode("children", FetchMode.JOIN); 
c.createCriteria("children", Criteria.LEFT_JOIN); 
c.add(Restrictions.eq("name", "John")); 
c.scroll(); 

、私は1つだけ子要素(代わりの2を期待して2つの親インスタンス(同じ参照)のリストを取得します)buが単一のSQLクエリを実行しています。

私はapiで何が間違っていますか?生成されたSQLを見ると同じです。

+0

これはHQLとCriteria APIの違いではなく、 'c.scroll()'と 'c.list()'と関係があるようです。私が質問を投稿したとき、HQLには 'query.list()'、Criteria APIには 'c.scroll()'を使いました。今私は4つのすべての組み合わせを試して、c.scroll()だけが予期しない動作をしていることを知りました。私はそれを修正する理由や方法を理解していません。 – Bhargava

+0

'scroll'の間のように、' session'はキャッシュ内の親の識別子だけを見ていて、それを新しい子の関連付けで更新しません。しかし、 'list'はキャッシュされた親オブジェクトを新しい子の関連付けで更新しているようです。私の推論は、それは同じオブジェクトに対して2つの異なる状態を与えたくないため、さらにスクロールするときにキャッシュされたオブジェクトを再び横切る場合、そのオブジェクトを更新しないということです。私は正しい?私は 'c.setCacheable(false)' /'c.setCacheable(true)を試しました。 c.setCacheMode(CacheMode.IGNORE/REFRESH) 'を実行しても効果はありません。 – Bhargava

+0

2つのクエリでオーダーされた親リストとオーダーされた子リストをスクロールする必要があるように見え、それらをプログラマティックに結合します。よりよいアプローチがあるのだろうかと思っています。 – Bhargava

答えて

0

私は似たような状況があり、ここでは(私の状況では少なくとも)と同等であるコードは次のとおりです。

Criteria c = session.createCriteria(Parent.class); 
c.setFetchMode("children", FetchMode.JOIN); 
c.add(Restrictions.eq("name", "John")); 

List<Parent> list = c.list(); 
Iterator<Parent> iter = list.iterator(); 

私はライン c.scroll();c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

に似た振る舞いを強制的という印象を持っています
+0

実際、それは私が観察したものではありません。 'DISTRINCT_ROOT_ENTITY'トランスが適用されている場合、' c.list() 'は2つの子を持つリスト内の1つの親インスタンスを返していました。 'c.scroll()'はこの結果トランスの影響を受けませんでした。 – Bhargava

+0

また、あなたのコードでは左結合が指定されていないことがわかります。自然結合は、デフォルトでは休止状態で選択されていると推測しています。 – Bhargava

+0

に1対多の関係が与えられている場合、左側の外部結合は 'FetchMode.JOIN'を設定したときに観測するデフォルトの動作です – iliaden

1

私は同じ問題を抱えていて、Hibernateのコードを使ってデバッグした後、あなたが間違っていることではなく、Hibernateのバグだと思います。

this Hibernate issueで修正されましたが、私たちの基準はまだスクロール可能な結果の不完全な子コレクションを返していました。 Loaderクラスには、FetchingScrollableResultsImplを使用して行を正しく処理するかどうかを決定するロジックがあり、needsFetchingScroll()は常にfalseを返すため、CriteriaLoaderは実行されません。しかし、QueryLoaderは、結合フェッチが使用されているときにそれを使用します。そのため、私たちの基準をHQLに変換して問題を解決したのです。

CriteriaLoader.needsFetchingScroll()を実装するためにHibernateにバグを報告するつもりです。

関連する問題