2012-07-12 7 views
7

NHibernateエンティティクラスで常にEquals/GetHashCodeをオーバーライドする必要があると説明されている多くの記事があります。セットを使用しない場合、これは本当に必要ですか?NHibernateでEquals/GetHashCodeを上書きする必要があるサンプルはありますか?

Equals/GetHashCodeが不足していると予期せぬ間違った動作をする可能性があるサンプルが見つかりません。すべてが完璧に機能しているようです。これは本当に誰もが必要だと言うのは奇妙ですが、の理由を示すサンプルを誰も提供することはできません。が必要です。

答えて

11

fetchが指定されていてもNHibernateが選択N + 1を実行しているため、最近SOにquestionがありました。行方不明のwasの問題Equals/GetHashCodeが実装されています。

回答は別の類似のリンクquestionにリンクしています。

another questionは、推論の理由がEquals/GetHashCodeになります。

Nhibernate n+1 with ternary relationship. Want the middle entity in the ternary
Nhibernate producing proxy despite HQL fetch
NHibernate: Reasons for overriding Equals and GetHashCode
Why Equals and GetHashCode are so important to NHibernate
Why is it important to override GetHashCode when Equals method is overridden?


編集

あなたはそれらをすべての時間をオーバーライドする必要はありません。コンポジットキー、分離されたエンティティまたはステートレスセッションを持つ複数のセッションを使用する場合は、必要な場合があります。

あなたが単一のセッションだけで作業している場合、NHibernateはアイデンティティマップを使って第1レベルのキャッシュにエンティティを保存します。その場合のエンティティの比較は、IDの比較によって行われます。

(分離されたエンティティ、ステートレスセッション)の場合、NHibernateはIDではなく実際のエンティティを比較します。既定では、Object.Equalsは参照の平等を行います。したがって、2つのオブジェクトがまったく同じインスタンスを指す場合、2つのオブジェクトは等しいです。同じIDを持つ2つのインスタンスがあるかもしれませんが、Object.Equalsfalseを返します。これはEntitydefinitionとは対照的である:

その属性によって定義されるのではなく、継続性とそのアイデンティティの スレッドがされていないオブジェクト。

のJBoss Hibernateのwikiには、いくつかのコード例でEqualsHashCodea good explanationを持っています。

+0

これは、複合キーにのみ関連するようです。私たちはそれらを使用しません。これがEquals/GetHashCOdeが必要な唯一のケースですあなたがリンクした最後の3つのリンクを知っています。間違った動作を再現するコードサンプルはありません。 – Antineutrino

+0

複合IDは1つの場合です。私はいくつかのテキストとHibernateのwikiページへのリンクで私の答えを更新しました... –

+0

+1リンクの印象的なコレクション。 –

4

実際、副作用の原因となるのはまれなケースのみです。しかし、あなたがそれらを手に入れれば、彼らはかなり微妙です。常に正しいEquals/GetHashCode実装が必要な複合主キーと辞書キーは別として

NHは、メモリ内で1回だけエンティティをインスタンス化することがあるので、デフォルトの参照比較が機能するはずです。がある場合は、が必要です。

Equalsをオーバーライドしないと、プロキシを処理するときに問題が発生します。 の2つのインスタンスがあります:プロキシと実体です。それらは両方とも同じエンティティを表します。 Equalsメソッドが正しく実装されている場合にのみ、それは同じものとして扱われます。

+0

これは、複合キーまたは辞書を使用しない場合、唯一の理由は、エンティティとそのプロキシを透過的にすることです。 – Antineutrino

+0

私が知っている唯一の理由。私たちはプロジェクトでEquals/GetHashCodeを実装しておらず、遅延ロードを使用するまで問題は発生しませんでした。 –

+0

私は、[この投稿](例:http://stackoverflow.com/a/5857854/200322)に、平等性が非常に簡単に失敗する可能性を示す例を追加しました。遅延ロードされたコレクションと比較されるオブジェクトがある場合は、プロキシと実際のエンティティを比較することになります(デフォルトの参照平等は失敗します)。 IMOでは、これらの問題をデバッグする際には、あなたの正気を救うために、常に "このような場合にのみ行うべき"とすべきではありません。 – TheCloudlessSky

関連する問題