I am using Hibernate 3.x.
I have a Staff object which has one-to-one association (many-to-one with unique constraint) with few objects. Since I have to send the Staff object back to the web-tier I create a DAO and therefore want to avoid lazy loading (reducing unnecessary trips to the DB). I thought that this could be done by setting fetch="join" in the Hibernate mapping. However, that has had no effect on the lazy loading. I do not understand why! Can someone explain?
I was able to avoid the lazy loading by using left joins in the query. I thought that the left joins could be used to avoid the lazy loading only if the fetch strategy was not fetch="join" See code snippet below.
The query which causes K*n + 1 queries to the DB. Where K is the number of objects in the table and n is the number of associations.
Code:
List<Staff> staffList = session.createQuery("from Staff").list();
for (Staff staff : staffList) {
basicStaffList.add(createBasicStaff(staff));
}
The Hibernate query generated by this:
Code:
Hibernate:
/*
from
Staff */ select
staff0_.id as id5_,
staff0_.contactInformation as contactI2_5_,
staff0_.accountInformation as accountI3_5_,
staff0_.dentalTreatmentsInformation as dentalTr5_5_
from
TC_Staff staff0_
Hibernate:
/* load staff.ContactInformation */
/* load staff.AccountInformation */
/* load staff.DentalTreatmentsInformation */
My Hibernate mapping :
Code:
<many-to-one name="contactInformation" column="contactInformation"
class="staff.ContactInformation"
unique="true" not-null="true" fetch="join" cascade="delete-orphan"/>
<many-to-one name="accountInformation" column="accountInformation"
class="staff.AccountInformation"
unique="true" not-null="true" fetch="join" cascade="delete-orphan"/>
<many-to-one name="dentalTreatmentsInformation" column="dentalTreatmentsInformation"
class="staff.DentalTreatmentsInformation"
unique="true" not-null="true" fetch="join" cascade="delete-orphan"/>
The example below is how I avoided the K*n + 1 query.
Code:
List<Staff> staffList = session.createQuery("from Staff staff " +
"left join fetch staff.contactInformation " +
"left join fetch staff.accountInformation " +
"left join fetch staff.dentalTreatmentsInformation").list();
for (Staff staff : staffList) {
basicStaffList.add(createBasicStaff(staff));
}
The Hibernate code generated for it.
Code:
Hibernate:
/*
from
Staff staff
left join
fetch staff.contactInformation
left join
fetch staff.accountInformation
left join
fetch staff.dentalTreatmentsInformation */ select
...
from
TC_Staff staff0_,
TC_ContactInformation contactinf1_,
TC_AccountInformation accountinf2_,
TC_DentalTreatmentsInformation dentaltrea4_
where
staff0_.contactInformation=contactinf1_.id(+)
and staff0_.accountInformation=accountinf2_.id(+)
and staff0_.dentalTreatmentsInformation=dentaltrea4_.id(+)
The above query works even if I remove the fetch="join" strategy.