Hibernate:对一对一关系的查询太多

时间:2012-04-25 21:10:55

标签: java sql hibernate one-to-one

短版

Hibernate正在进行多个选择查询,而不是只有两个,以检索一对一的关系

长版

人类:

@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());
}

我的期望:两个选择,一个用于五个人,一个用于三个不同的工作(三个人有相同的工作)

我得到了:四个选择,一个用于人,三个用于他们各自的工作

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

如果我有1000个人有1000个不同的工作,我会看到1000个选择被执行。我怎么能这样做Hibernate只做两个选择?

由于

2 个答案:

答案 0 :(得分:7)

这是n + 1问题的一个示例,Hibernate manual 建议使用JOIN获取模式。您可以使用特定于hibernate的注释

启用此功能
@Fetch(FetchMode.JOIN)

答案 1 :(得分:2)

你没有一对一的关系,你有一对多的关系。一份工作可以附加多个人。 Hibernate假设实际上存在一对一的关系而没有注意到三个人指向一个工作。 然后你必须解决N + 1选择问题,正如beerbajay指出的那样。