654

私は Java Persistence API と Hibernate の初心者です。

Java Persistence APIのFetchType.LAZYとの違いは何ですか?FetchType.EAGER

4

17 に答える 17

1265

2 つのエンティティがあり、それらの間に関係がある場合があります。たとえば、エンティティと呼ばれるUniversity別のエンティティがStudentあり、大学には多くの学生がいるとします。

University エンティティには、id、名前、住所などのいくつかの基本的なプロパティと、特定の大学の学生のリストを返す学生と呼ばれるコレクション プロパティがあります。

大学にはたくさんの学生がいます

public class University {
   private String id;
   private String name;
   private String address;
   private List<Student> students;

   // setters and getters
}

これで、データベースから大学をロードすると、JPA が ID、名前、およびアドレス フィールドをロードします。ただし、学生の読み込み方法には 2 つのオプションがあります。

  1. 残りのフィールドと一緒にロードするには (すなわち熱心に)、または
  2. getStudents()大学のメソッドを呼び出すときに、オンデマンドで (つまり遅延して) ロードします。

大学に多くの学生がいる場合、すべての学生を一緒にロードするのは効率的ではありません。特に、学生が必要でない場合はそうです。このような場合、学生が実際に必要なときに学生をロードするように宣言できます。これは遅延読み込みと呼ばれます。

これは例です。ここでstudentsは、熱心に読み込まれるように明示的にマークされています。

@Entity
public class University {

    @Id
    private String id;

    private String name;

    private String address;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Student> students;

    // etc.    
}

studentsそして、遅延ロードするように明示的にマークされている例を次に示します。

@Entity
public class University {

    @Id
    private String id;

    private String name;

    private String address;

    @OneToMany(fetch = FetchType.LAZY)
    private List<Student> students;

    // etc.
}
于 2010-06-07T15:53:56.430 に答える
330

基本的、

LAZY = fetch when needed
EAGER = fetch immediately
于 2010-06-07T15:31:16.860 に答える
74

EAGERコレクションのロードとは、親がフェッチされた時点でコレクションが完全にフェッチされることを意味します。したがって、 がありCourse、 が ある場合、 が取得された時点List<Student>ですべての学生がデータベースからCourse取得されます。

LAZY一方、の内容は、Listアクセスしようとしたときにのみ取得されることを意味します。たとえば、 を呼び出しcourse.getStudents().iterator()ます。で任意のアクセス メソッドをList呼び出すと、データベースへの呼び出しが開始され、要素が取得されます。Listこれは、 (または)の周りにプロキシを作成することによって実装されSetます。したがって、遅延コレクションの場合、具象型はArrayListandHashSetではなくPersistentSetand PersistentList(or PersistentBag)です。

于 2010-06-07T15:54:39.220 に答える
19

パフォーマンスとメモリ使用率を考慮する場合があります。大きな違いの 1 つは、EAGER フェッチ戦略では、フェッチされたデータ オブジェクトをセッションなしで使用できることです。なんで?
セッションが接続されたときにオブジェクト内のデータを熱心にマークすると、すべてのデータがフェッチされます。ただし、遅延読み込み戦略の場合、セッションが切断されている場合 (session.close()ステートメントの後)、マークされたオブジェクトの遅延読み込みはデータを取得しません。休止状態のプロキシによって作成できるすべて。Eager 戦略により、セッションを閉じた後もデータを引き続き利用できます。

于 2013-01-29T02:39:22.720 に答える
11

と の両方FetchType.LAZYFetchType.EAGER使用して、デフォルトのフェッチ プランを定義します。

残念ながら、LAZY fetching のデフォルトのフェッチ プランのみをオーバーライドできます。EAGER フェッチは柔軟性が低く、多くのパフォーマンスの問題を引き起こす可能性があります。

私のアドバイスは、フェッチはクエリ時の責任であるため、アソシエーションを EAGER にする衝動を抑えることです。そのため、すべてのクエリでfetchディレクティブを使用して、現在のビジネス ケースに必要なものだけを取得する必要があります。

于 2014-11-09T07:31:58.320 に答える
9

2 つのタイプのフェッチの主な違いは、データがメモリにロードされる瞬間です。
これを理解するのに役立つ2枚の写真を添付し​​ました。

イーガーフェッチ
イーガーフェッチ

遅延フェッチ 遅延フェッチ

于 2020-05-25T08:27:43.647 に答える
6

Javadocから:

EAGER 戦略は、永続化プロバイダーのランタイムで、データを熱心にフェッチする必要があるという要件です。LAZY 戦略は、データが最初にアクセスされたときにデータを遅延して取得する必要があるという持続性プロバイダーのランタイムへのヒントです。

たとえば、熱心は怠惰より積極的です。Lazy は最初の使用時にのみ発生しますが (プロバイダーがヒントを取得した場合)、Eager の場合は (可能性があります) プリフェッチされます。

于 2010-06-07T15:31:35.687 に答える
1

public enum FetchType extends java.lang.Enum データベースからデータを取得するための戦略を定義します。EAGER 戦略は、永続化プロバイダーのランタイムで、データを熱心にフェッチする必要があるという要件です。LAZY 戦略は、データが最初にアクセスされたときにデータを遅延して取得する必要があるという持続性プロバイダーのランタイムへのヒントです。実装は、LAZY 戦略ヒントが指定されているデータを積極的にフェッチすることが許可されています。例: @Basic(fetch=LAZY) protected String getName() { return name; }

ソース

于 2016-08-29T16:10:20.353 に答える
0

@drop-shadow Hibernate を使用している場合は、メソッドHibernate.initialize()を呼び出すときに呼び出すことができます。getStudents()

Public class UniversityDaoImpl extends GenericDaoHibernate<University, Integer> implements UniversityDao {
    //...
    @Override
    public University get(final Integer id) {
        Query query = getQuery("from University u where idUniversity=:id").setParameter("id", id).setMaxResults(1).setFetchSize(1);
        University university = (University) query.uniqueResult();
        ***Hibernate.initialize(university.getStudents());***
        return university;
    }
    //...
}
于 2014-03-06T09:06:04.403 に答える