4

休止状態基準を使用する場合、結合タイプを変更するだけで、ルート ドメイン クラスの子コレクションの結果に影響します。

たとえば、次のデータを使用して、クラス Parent をクラス Child と 1 対多の関係にします。

親
| | ID | 名前 |
| | 1 | 親 1 |

子
| | ID | 親 ID | 名前 |
| | 1 | 1 | 子1 |
| | 2 | 1 | 子2 |

次の hibernate 基準を使用すると、1 つの親行が返され、子コレクションにアクセスすると、2 つの行が返されます。

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.INNER_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

ただし、左結合で上記のコードを変更すると、1 つの親行が返されますが、子コレクションにアクセスすると、一致する子行のみが返されます。

session.createCriteria(Parent.class)
    .createCriteria('child', CriteriaSpecification.LEFT_JOIN)
    .add( Restrictions.eq( 'name', 'Child1' ) )
    .list()

この副作用はなぜ起こるのでしょうか?意図した結果に応じて、この副作用を使用または回避することについてのいくつかの議論を見つけましたが、そもそもなぜそれが存在するのか、それが意図されていたのかどうかについては何もありません. 最も直接的な質問は、古い古い欠陥 ( http://opensource.atlassian.com/projects/hibernate/browse/HHH-3872 ) です。

  • EDIT 3/24: 固定データ *
4

2 に答える 2

1

この問題はここで説明されており、Hibernate3.6で修正されているようです

https://hibernate.onjira.com//browse/HHH-2049

于 2011-07-11T12:13:20.477 に答える
0

私はこれを試しました:このクエリを実行し、その後parent.getChildren()を呼び出すとき:

  • LEFT JOIN: 親と 1 つの一致する子を含む 1 つのクエリが実行され、getChildren() の呼び出し時に後続のクエリは実行されません。
  • INNER_JOIN: 2 つのクエリが実行されます。1 つは一致する子を持つ親を検索するためのもので、もう 1 つは getChildren() を呼び出す場合です。

そのため、LEFT_JOIN を呼び出すと、子 (この場合は一致する子) が EAGERLY フェッチされ、Parent の子コレクションが既に取り込まれているようです。ただし、INNER_JOIN の場合、このコレクションはプロキシとしてマークされ、getChildren() の呼び出し時に初期化されます。もちろん、この 2 番目のクエリでは、名前の制限が考慮されなくなり、親のすべての子が単純に取得されます。

これは、休止状態の「内部」で発生するようです。つまり、結合タイプは、休止状態が結果を処理する方法に影響します。左結合と内部結合の間で生成された SQL はわずかに異なりますが (私のテストでは、parent.id と child.id は select 句で 2 回使用されていました)、DB ブラウザーで SQL を実行したときに返される結果は同じです。

これがバグかどうかを判断するのに十分な経験はありませんが、バグのようには感じません。

于 2011-03-22T12:43:13.923 に答える