web-dev-qa-db-ja.com

Hibernateでの一対一、多対一、および一対多のデフォルトのフェッチタイプ

Hibernateマッピングのデフォルトのフェッチタイプは何ですか?

探索した後に知ったのは:

  • 1対1の場合、eagerです。
  • 1対多の場合はlazyです。

しかし、Eclipseでテストした後は、すべてに熱心でした。

JPAまたはHibernateのどちらを使用しているかによって異なりますか?

80
Richa

JPAまたはHibernateのどちらを使用しているかによって異なります。

JPA 2.0仕様 から、デフォルトは次のとおりです。

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

そして、休止状態では、すべてが怠zyです

UPDATE:

Hibernateの最新バージョンは、上記のJPAのデフォルトと一致しています。

146
Ashish Agarwal

質問をした時点で答えが正しかったことは知っていますが、人々(今のように)は、彼らのWildFly 10の動作が違うのではないかと思っているので、現在のHibernate 5のアップデートを提供したいと思います。 .xバージョン:

Hibernate 5.2 User Guide には、章11.2に記載されています。フェッチ戦略の適用

Hibernateの推奨事項は、すべてのアソシエーションを遅延的に静的にマークし、熱心に動的フェッチ戦略を使用することです。残念ながら、これはすべての1対1および多対1の関連付けをデフォルトで積極的にフェッチする必要があると定義しているJPA仕様と矛盾しています。 HibernateはJPAプロバイダーとして、そのデフォルトを尊重します。

したがって、HibernateはJPAについて前述したAshish Agarwalのように動作します。

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

JPA 2.1仕様 を参照)

50
Alexander Rühl

あなたの質問に答えるために、HibernateはJPA標準の実装です。 Hibernateには独自の動作の癖がありますが、 Hibernate docs

デフォルトでは、Hibernateはコレクションに対して遅延選択フェッチを使用し、単一値の関連付けに対して遅延プロキシフェッチを使用します。これらのデフォルトは、ほとんどのアプリケーションのほとんどの関連付けに意味があります。

したがって、Hibernateは、どのタイプのリレーションシップを宣言しても、常に遅延フェッチ戦略を使用してオブジェクトをロードします。 1対1または多対1の関係にある単一のオブジェクトに対してレイジープロキシ(初期化されていないがnullでない)と、アクセスしようとしたときに値でハイドレートするnullコレクションを使用します。

fetchType.EAGERを指定しない限り、Hibernateはオブジェクトにアクセスしようとしたときにのみこれらのオブジェクトに値を入力しようとすることを理解しておく必要があります。

15
JamesENL

単一の値の関連付けの場合、つまり-One-to-OneおよびMany-to-One:-
デフォルトのLazy = proxy
プロキシレイジーロード:-これは、関連するエンティティのプロキシオブジェクトがロードされることを意味します。これは、2つのエンティティを接続するIDのみが、関連付けられたエンティティのプロキシオブジェクトに対してロードされることを意味します。
たとえば、AとBは、多対1の関連付けを持つ2つのエンティティです。つまり、Bごとに複数のAが存在する場合があります。Aのすべてのオブジェクトには、Bの参照が含まれます。
`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
リレーションAには列(aid、bid、...エンティティAの他の列)が含まれます。
リレーションBには列(bid、...エンティティBの他の列)が含まれます

プロキシは、Aがフェッチされると、BのIDのみがフェッチされ、IDのみを含むBのプロキシオブジェクトに格納されることを意味します。 Bのプロキシオブジェクトは、最小限のフィールドのみを持つBのサブクラスであるプロキシクラスのオブジェクトです。入札はすでにリレーションAの一部であるため、リレーションBから入札を取得するためにクエリを起動する必要はありません。エンティティBの他の属性は、入札以外のフィールドにアクセスした場合にのみ遅延ロードされます。

コレクションの場合、-多対多および一対多:-
デフォルトのLazy = true


フェッチ戦略(select、joinなど)は遅延をオーバーライドできることに注意してください。例:lazy = 'true'およびfetch = 'join'の場合、AのフェッチはBまたはBs(コレクションの場合)もフェッチします。考えれば理由を知ることができます。
単一値の関連付けのデフォルトのフェッチは「結合」です。
コレクションのデフォルトのフェッチは「select」です。最後の2行を確認してください。私はそれを論理的に推測しました。

0
Jijo Mathew