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@ManyToOneEAGER、注釈の場合@OneToMany@ManyToManyLAZY です。覚えておくと簡単です。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