2009-10-01 7 views
11

私は、Hibernateで1対多の関連付けを行うときに、ほとんどの人がコレクション型として使うものを探しています。私が保守しているレガシーアプリケーションは、バッグを排他的に使用しますが、コードとしてリストとして保持します。関連付けられたテーブルにはidフィールドがあるので、idbagはより適切ですが、ドキュメンテーションはSetを推奨します。Hibernate:ベストコレクションタイプ - バッグ、idbag、セット、リスト、マップ

EDIT:ドキュメントがセットを推奨していると間違って参照しました。現実には、公式の文書は、すべてのコレクションタイプで同じように曖昧です。私は何を見つけることsomewebsitesは設定が最も一般的であることを推測するように見えるということである、と私は明示的に読んでいるHibernateの本はセットについて、これを言う:

これは典型的なHibernateのアプリケーションで最も一般的な持続的なコレクションです。 (参照:クリスチャン・バウアーとGavin King氏によって「Hibernateを使ったJavaの永続化」のページ242)

私はそれが私を投げ、私は他の人が使っているものを模索作ったものであると思います。

EDIT2:Gavin King氏は、私が:-)、人々はあらゆる種類のものを使用して休止状態

+0

私は、HibernateToolsリバースエンジニアリングツールがSetを使って私のPOJOドメインオブジェクトをほとんど排他的に作成したので、Setが推奨されたという印象を受けました。 – Marvo

答えて

9

かなり時間の経過した後、コレクションタイプとしてSetを使用しない理由が見つかりました。 hashcode/equalsオーバーライドの問題とhibernateの存続方法が原因で、hashcode/equalsを呼び出すjava API機能を使用することは悪い考えです。永続性の前後でオブジェクトを一貫して比較する良い方法はありません。 bagのように、等号/ハッシュコードに依存しないコレクションに固執する。ここ

さらに詳しい情報:

http://community.jboss.org/wiki/EqualsandHashCode(このリンクは、ビジネスキーが移動するための方法であるように、それは聞こえるが、それは常に良い考えではありません理由は完全に次のリンクを読む)

https://forum.hibernate.org/viewtopic.php?f=1&t=928172(あなたの頭を回転させるための議論全体を読む)

5

の生みの親推測されていることに注意してください - 「最高」1はあなたが必要なものに依存して異なるコレクション型は、異なる目的を果たしますそれのために。

つまり、コードでListを使用する方が、Listが順序付けられていないにもかかわらず、Setを使用するより便利です。それ以外の場合は、.iterator().next()よりも目の前で '.get(0)'の方が簡単です:-) Hibernateのバッグサポートは、この目的にはまったく相応しく、さらにorder-by宣言を追加してリストをソートすることもできます。

idbagは、多対多の関連付けに使用される完全に異なる動物です。あなたは本当にそれを通常のSetやListと比較することはできません。

+1

ChssPly76によると: "Listを使用するよりも、Listを使用したほうが便利ですが、それ以外の場合は、.iter()。next()私はこれに同意します。これは、すべてのドキュメントがセットを推奨したときに私を投げたものです。私は他の人が何を使っているのか、それがドキュメンテーションに反しているのか見たいだけです。ありがとう。 – Nemi

+0

「ドキュメンテーションはセットを推奨しています。あなたは特定のリンクを提供できますか?私は、Hibernateのドキュメンテーションが別のコレクション型よりも1つのコレクション型を推奨しているとは思わない(どのようにそれができますか?利用可能なさまざまなマッピングを記述するだけです。コレクションの章には1つの「お勧め」という単語はありません:http://docs.jboss.org/hibernate/stable/core/reference/en/html/collections.html – ChssPly76

+0

@ ChssPly76 - もちろん正しい。上記の私の編集をご覧ください。 – Nemi

2

セットはユニークなアイテムのコレクションとして定義され、通常は対処するものなので、セットを使用することをお勧めします。

.iterator().next()は、コレクションに要素がない場合に保存されます。

.get(0)空リストにアクセスすると、IndexOutOfBoundsExceptionが返されることがあります。

+7

Riiiiight ...それを試すケア? 'iterator()。hasNext()'は安全です。 'iterator()。next()'は最も確実ではありません。 – ChssPly76

+1

もちろん、iterators hasNextメソッドを使ってチェックしますが、要素がリスト内のどの位置にあるかはわかりません。 – MrWhite

+2

リストが空であるかどうかをチェックするだけでいいです( 'isEmpty()'を経由して、もう一度読むことができます)。私はあなたが「どのポジション」を意味するのかよくわかりません。リストとセットを比較する方法を見て、あなたのリストは順序どおりに並べられません。 – ChssPly76

12

両方を使った経験に基づいて、私はリストを使うことを勧めます。データをデータベースから取り出して表示/操作している場合は、ほぼ常に一貫した順序で保管する必要があります。あなたはSortedSetを使うことができますが、これは順序を追加してListに格納するのと比べて、痛みの世界を追加することができます(equals、hashcodeなどのオーバーライド、さまざまな方法によるソート)。リストの操作が簡単です。ユーザーがページの3行目を削除した場合、リスト内の項目3を削除するだけです。セットを使って作業すると、たくさんの不要なコードが含まれ、イテレータについて混乱するようです。

私はHibernateでSetsを使用していたとき、Setが数多くの制限を与えているため、数週間後にすべてのSetsをリッピングしてListに置き換えることがよくありました。

Hibernateのドキュメントとサードパーティのツールは、デフォルトでセットを使用しているようですが、難しい経験から、リストを使用するほうがはるかに生産性が高いことがわかりました。

関連する問題