2.1 フェッチオプション
Hibernate の開発者は、子エンティティのロードに関する問題については長い間認識していました。そこで彼らが最初に行ったのは、特別なフェッチパラメータをアノテーションに追加することでした@OneToMany
。@ManyToMany
このパラメータには次の 2 つの値を指定できます。
- 熱心
- 怠惰
例:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
fetch パラメータが EAGER に等しい場合、親エンティティがロードされると、そのすべての子エンティティもロードされます。また、Hibernate は 1 つの SQL クエリでそれを実行しようとし、大量のクエリを生成してすべてのデータを一度にフェッチします。
fetch パラメータが値 LAZY を取る場合、親エンティティがロードされるときに、子エンティティはロードされません。代わりに、プロキシ オブジェクトが作成されます。
このプロキシ オブジェクトの助けを借りて、Hibernate はこの子エンティティへのアクセスを追跡し、初めてアクセスされたときにそれをメモリにロードします。
コメントで状況を思い出してみると、次のようになります。
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
public List<Comment> comments;
}
次に、「シックな選択」があります。
の場合fetch = FetchType.EAGER
、Hibernate はコードの 1 行目にあるすべてのコメントをロードします。
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
の場合fetch = FetchType.LAZY
、Hibernate はコードの 2 行目にあるすべてのコメントをロードします。
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here
すでにご想像のとおり、すべてのコメントが読み込まれない場合は選択肢がありません:)
2.2 デフォルト値
... アノテーションのフェッチ オプションを指定しない場合@ManyTo
、Hibernate はデフォルト値を使用します。
これらは注釈の種類によって若干異なります。注釈の場合@OneToOne
は@ManyToOne
EAGER、注釈の場合@OneToMany
は@ManyToMany
LAZY です。覚えておくと簡単です。1 つのオブジェクトを参照すると、そのオブジェクトは完全にロードされます。コレクションを参照する場合、コレクションは最初にアクセスされたときにロードされます。
2.3 @LazyCollection アノテーション
すでに見たように、コレクションを操作する場合、fetch パラメータはあまり役に立ちません。Hibernate の作成者は、特別なアノテーションを追加することでこの問題を修正しようとしました@LazyCollection
。通常は次のように書かれます。
@LazyCollection(LazyCollectionOption.TRUE)
コレクションフィールドをマッピングするときに指定する必要があります。
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
このアノテーションには、次の 3 つの値のいずれかを取れる value パラメーターがあります。
- LazyCollectionオプション。真実
- LazyCollectionオプション。間違い
- LazyCollectionオプション。追加
最初の 2 つのオプションは、fetch オプションと非常によく似ています。
パラメーターが に設定されている場合、親 User オブジェクトがロードされるときに、LazyCollectionOption.TRUE
コメント フィールドの値がデータベースからロードされないことを意味します。コメント タイプのオブジェクトは、コメント フィールドに初めてアクセスしたときにロードされます。実際、これはパラメータと同等です。FetchType.LAZY
パラメータが に設定されている場合、親 User オブジェクトのロード時にLazyCollectionOption.FALSE
コメント フィールドの値がデータベースからロードされることを意味します。コメント タイプのオブジェクトは、コメント フィールドに初めてアクセスしたときにロードされます。実際、これは と同等ですFetchType.EAGER
。