web-dev-qa-db-ja.com

Hibernate @LazyCollectionアノテーションの用途は何ですか

親としての2つのエンティティとOneToManyリレーションとしての子があります。

@Entity
public class Parent {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

private String name;

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
@IndexColumn(name = "index", base = 1)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Child> childs = new ArrayList<Child>();
// getter and setter

}

したがって、ここでは@ LazyCollection(LazyCollectionOption.EXTRA)の使用方法と、子リストを使用するどの操作のように、いつ表示されるかを説明します。

31
Rahul Agrawal

ヒントとして、主にパフォーマンス上の理由から、次のリンクを読み始めることができます。

2次キャッシュ

Hibernateのドキュメント

8
Maddy

[〜#〜] extra [〜#〜] = .size()および.contains()はコレクション全体を初期化しません

[〜#〜] true [〜#〜] =最初のアクセスでコレクション全体を初期化します

[〜#〜] false [〜#〜] =熱心な読み込み

31
wutzebaer

これは非常に良い質問なので、この答えを 記事も に変えることにしました。

_@LazyCollection_を使用する理由は実際にはありません。

JPA _FetchType.LAZY_または _FetchType.EAGER_ でも同じ動作が得られるため、TRUEおよびFALSE値は必要ありません。

EXTRA値はJPAに相当するものはなく、非常に大きなコレクション用に設計されました。 EXTRAレイジーコレクションに初めてアクセスするとき、通常はすべてのJPAコレクションに当てはまるため、コレクションは完全にはロードされません。

代わりに、セカンダリSELECTを使用して、各要素が1つずつフェッチされます。これは最適化のように聞こえるかもしれませんが、EXTRA遅延コレクションが N + 1クエリの問題 を起こしやすいためではありません。

これは、順序付けられたコレクション、つまり_@OrderColumn_で注釈されたList(s)またはMap(s)でのみ機能することに注意してください。バッグ(たとえば、特定の順序を保持しないエンティティの通常のList(s))の場合、@LazyCollection( LazyCollectionOption.EXTRA )は他のLAZYコレクションと同じように動作します(コレクションがフェッチされます)完全に初めてアクセスされたとき)。

コレクションが非常に大きい場合は、まったくマップしないでください。代わりに、_@ManyToOne_側のみをマップし、親側のコレクションではなく、ページ分割されたJPQLクエリを使用する必要があります。

JPQLクエリは、任意のフィルタリング基準を適用でき、結果セットにページ番号を付けることができるため、調整がはるかに簡単です。

18
Vlad Mihalcea