3

短縮版

Hibernate は 1 対 1 の関係を取得するために 2 つだけではなく複数の選択クエリを実行しています

ロングバージョン

人物クラス:

@Entity
@Table(name = "people")
public class Person{

  @Id
  @GeneratedValue
  @Column
  private Integer id;

  @Column
  private String name;

  @OneToOne(optional=false, fetch=FetchType.EAGER)
  private Job job;
}

ジョブ クラス:

@Entity
@Table(name = "jobs")
public class Job{

  @Id
  @GeneratedValue
  @Column
  private Integer id;

  @Column
  private String name;
}

すべての人とその仕事を表示する:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<Person> people = session.createQuery("from Person").list();
for(Person p : people){
    System.out.println(p.getName() + " | " + p.getJob().getName());
}

私が期待したこと: 2 つの選択、1 つは 5 人用、もう 1 つは 3 つの異なる仕事用 (3 人が同じ仕事をしています)

私が得たもの: People 用に 1 つ、それぞれの異なる Job 用に 3 つの 4 つの選択

Hibernate: select person0_.id as id1_, person0_.job_id as job3_1_, person0_.name as name1_ from people person0_
Hibernate: select job0_.id as id0_0_, job0_.name as name0_0_ from jobs job0_ where job0_.id=?
Hibernate: select job0_.id as id0_0_, job0_.name as name0_0_ from jobs job0_ where job0_.id=?
Hibernate: select job0_.id as id0_0_, job0_.name as name0_0_ from jobs job0_ where job0_.id=?
Jim | Programmer
Andrew | DBA
Tomas | Sysadmin
Henry | Sysadmin
Jerry | Sysadmin

1,000 の異なるジョブを持つ 1,000 人がいる場合、1,000 の選択が実行されていることがわかります。Hibernate が 2 つの選択のみを行うようにするにはどうすればよいですか?

ありがとう

4

2 に答える 2

8

これは、 Hibernate マニュアルがフェッチ モードの使用を推奨しているn + 1問題の例です。これは、休止状態固有の注釈で有効にできますJOIN

@Fetch(FetchMode.JOIN)
于 2012-04-25T21:26:37.700 に答える
2

1 対 1 の関係ではなく、1 対多の関係があります。1 つのジョブに複数のユーザーを関連付けることができます。Hibernate は、実際には 1 対 1 の関係があると想定しており、3 人が 1 つのジョブを指していることに気づいていません。次に、beerbajay が指摘するように、N+1 選択の問題を解決する必要があります。

于 2012-04-25T21:27:39.750 に答える