JPAのフェッチ戦略は正確には何を制御しますか?熱心なものと怠惰なものの違いを検出できません。どちらの場合も、JPA / Hibernateは多対1の関係を自動的に結合しません。
例:人は単一の住所を持っています。アドレスは多くの人に属することができます。JPAアノテーション付きエンティティクラスは次のようになります。
@Entity
public class Person {
@Id
public Integer id;
public String name;
@ManyToOne(fetch=FetchType.LAZY or EAGER)
public Address address;
}
@Entity
public class Address {
@Id
public Integer id;
public String name;
}
JPAクエリを使用する場合:
select p from Person p where ...
JPA / Hibernateは、Personテーブルから選択する1つのSQLクエリを生成し、次に各個人の個別のアドレスクエリを生成します。
select ... from Person where ...
select ... from Address where id=1
select ... from Address where id=2
select ... from Address where id=3
これは、大きな結果セットの場合は非常に悪いです。1000人の場合、1001クエリが生成されます(Personからのクエリが1つ、Addressからのクエリが1000)。これは、MySQLのクエリログを見ているのでわかります。アドレスのフェッチタイプをeagerに設定すると、JPA / Hibernateが結合を使用して自動的にクエリを実行することを理解しました。ただし、フェッチの種類に関係なく、リレーションシップに対して個別のクエリが生成されます。
参加するように明示的に指示した場合にのみ、実際に参加します。
select p, a from Person p left join p.address a where ...
ここで何か不足していますか?多対1の関係を結合するように、すべてのクエリを手動でコーディングする必要があります。MySQLでHibernateのJPA実装を使用しています。
編集: JPAクエリに影響を与えないように見えます(Hibernate FAQのこことここを参照)FetchType
。したがって、私の場合は、参加するよう明示的に指示しています。