Breno Gazzola
Breno Gazzola

Reputation: 2162

Hibernate: Too many queries for a One to One relationship

Short Version

Hibernate is doing multiple select queries instead of only two to retrieve a one to one relationship

Long Version

Person Class:

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

Job Class:

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

  @Id
  @GeneratedValue
  @Column
  private Integer id;

  @Column
  private String name;
}

Displaying all People and their Jobs:

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

What I expected: Two selects, one for the five People and one for their three different Jobs (three people have the same job)

What I got: Four selects, one for People and three for each of their different Jobs

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

If I had 1000 people with 1000 different jobs, I would see 1000 selects being executed. How can I make it so Hibernate only does two selects?

Thanks

Upvotes: 4

Views: 6059

Answers (2)

Jim Barrows
Jim Barrows

Reputation: 3634

You don't have a one-to-one relationship, you have a one-to-many relationship. A job can have multiple people attached to it. Hibernate is assuming that there is actually a one-to-one relationship and not noticing that three people are pointing at 1 job. Then you have to solve the N+1 selects problem, as beerbajay points out.

Upvotes: 3

beerbajay
beerbajay

Reputation: 20270

This is an example of the n + 1 problem, for which the Hibernate manual suggests using the JOIN fetch mode. You can enable this with the hibernate-specific annotation

@Fetch(FetchMode.JOIN)

Upvotes: 9

Related Questions