views:

114

answers:

2

So I've been dealing with a home brew DB framework that has some seriously flaws, the justification for use being that not using an ORM will save on the number of queries executed.

If I'm selecting all possibile records from the top level of a joinable object hierarchy, how many separate calls to the DB will be made when using an ORM (such as Hibernate)?

I feel like calling bullshit on this, as joinable entities should be brought down in one query , right? Am I missing something here?

note: lazy initialization doesn't matter in this scenario as all records will be used.

A: 

Bobah is right,

You should give hibernate a try in order to see how many request will be sent to the database, however, in hibernate you can also specify and tune specific request by using HQL.

In addition with hibernate tools, you could also use P6spy driver, so you'll be able to see all the request that hibernate send to your database, with the value for each filter of the request.

zor
A: 

Hibernate will almost always retrieve object hierarchies using a single query; I don't recall seeing it do otherwise. It's easy to test, anyway. With this very simple mapping:

@Entity
public static class Person {
    @Id
    public String name;
}

@Entity
public static class Student extends Person {
    public float averageGrade;
}

@Entity
public static class Teacher extends Person {
    public float salary;
}

Then Hibernate gives me the following results for a very simple browse query (sessionFactory.openSession().createCriteria(Person.class).list();).

With @Inheritance(strategy = InheritanceType.SINGLE_TABLE) on the parent:

select this_.name as name0_0_, this_.averageGrade as averageG3_0_0_, 
  this_.salary as salary0_0_, this_.DTYPE as DTYPE0_0_ from HibernateTest$Person this_

With @Inheritance(strategy = InheritanceType.JOINED) on the parent:

select this_.name as name0_0_, this_1_.averageGrade as averageG1_1_0_, 
  this_2_.salary as salary2_0_, case when this_1_.name is not null then 1 
  when this_2_.name is not null then 2 when this_.name is not null then 0 
  end as clazz_0_ from HibernateTest$Person this_ left outer 
  join HibernateTest$Student this_1_ on this_.name=this_1_.name left outer join
  HibernateTest$Teacher this_2_ on this_.name=this_2_.name

With @Inheritance(strategy = InheritanceType.JOINED) on the parent:

select this_.name as name0_0_, this_.averageGrade as averageG1_1_0_, 
  this_.salary as salary2_0_, this_.clazz_ as clazz_0_ from 
  ( select null as averageGrade, name, null as salary, 0 as clazz_ 
  from HibernateTest$Person union select averageGrade, name, null as salary, 
  1 as clazz_ from HibernateTest$Student union select null as averageGrade, 
  name, salary, 2 as clazz_ from HibernateTest$Teacher ) this_

As you can see, each is one query, with JOINs or UNIONs as appropriate depending on the mapping type.

Cowan