2013-12-21 15 views
9

多くのJPA関連では、空のコレクションとの関係を初期化するのがベストプラクティスと考えられますか?例えば。上記の例でJPA関係マッピングを初期化するか、初期化しないか?

@Entity 
public class Order { 

    @Id 
    private Integer id; 

    // should the line items be initialized with an empty array list or not? 
    @OneToMany(mappedBy="order") 
    List<LineItem> lineItems = new ArrayList<>(); 

} 

は、空でArrayListかどうかのデフォルト値とlineItemsを定義することが良いですか?長所と短所は何ですか?

答えて

13

JPA自体はコレクションが初期化されているかどうかは気にしません。 JPAを使用してデータベースからOrderを取得する場合、JPAはと常に一致します。は、OrderLinesのnull以外のリストを持つOrderを返します。

理由:オーダーは0行、1行またはN行を持つことができ、空、1サイズまたはNサイズのコレクションでモデル化するのが最適です。コレクションがnullの場合は、コード内のどこでもそのコレクションをチェックする必要があります。リストがnullだった場合たとえば、この単純なループは、NullPointerExceptionが引き起こす:

for (OrderLine line : order.getLines()) { 
    ... 
} 

をだから、常にでもエンティティの新規作成されたインスタンスに対して、null以外のコレクションを持つことにより、不変ことを確認するのが最善です。これにより、生産コードはより安全で清潔な新しい注文を作成できます。これはまた、データベースから来ていないOrderインスタンスを使用して、より安全でクリーンなユニットテストを行います。私はまた、例えば、グアバの不変コレクションを使用することをお勧めします

2

import com.google.common.collect.ImmutableList; 
// ... 
@OneToMany(mappedBy="order") 
List<LineItem> lineItems = ImmutableList.of(); 

このイディオムは決して新しい空のリストを作成しませんが、空のリストを表す単一のインスタンスを再利用(タイプは関係ありません)。これは関数型プログラミング言語の非常に一般的な習慣であり(Scalaも同様)、ゼロにヌル値の代わりに空のオブジェクトを持つオーバーヘッドを減らし、イディオムmootに対して効率的な引数を与えます。

+0

この便利なコメントありがとうございます。 – cripox

+1

しかし、JPAエンティティの場合は、_mutable_リストで初期化し、フィールドをプライベートにして、コレクションにパブリックゲッターを提供する必要があると主張します。このようにして、 'lineItems'は決して' null'ではないことを確信できます。現代のJVMはガベージコレクションではかなり良いので、空のリストを作成することについては心配しません。一般的な注意点として、コードをあらかじめ最適化しないでください! –

+0

私は@StefanHaberlに同意します。エンティティフィールドを不変なコレクションで初期化するべきではありません。これにより、エンティティの新しいインスタンスが作成され、テストが困難になります。あなたがパフォーマンスについて心配しているなら、 '新しいHashSet <>(0)'(https://stackoverflow.com/questions/18076492/why-initialize-hashset0-to-zero)のようなものを試してみてください。 – csharpfolk

関連する問題