Consider a simple class heirarchy
Code:
@Entity
@Table(name = "ABSTRACTEMPLOYEE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class AbstractEmployee {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME")
private String name;
@Column(name = "ADDRESS")
private String address;
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
private Car car;
.
.
.
}
This query gets around the N+1 select issue for the Car objects by using LEFT JOIN FETCH
Code:
emp = (List<AbstractEmployee>) session.createQuery("from AbstractEmployee a LEFT JOIN FETCH a.car").list();
The SQL generated is pretty sane:
Code:
Hibernate: /* from AbstractEmployee a LEFT JOIN FETCH a.car */ select abstractem0_.ID as ID2_0_, car1_.ID as ID1_1_, abstractem0_.ADDRESS as ADDRESS2_0_, abstractem0_.car_ID as car5_2_0_, abstractem0_.NAME as NAME2_0_, abstractem0_2_.CE_HOURLYRATE as CE1_4_0_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_0_, abstractem0_.DTYPE as DTYPE2_0_, car1_.LICENSEPLATEID as LICENSEP2_1_1_, car1_.MAKE as MAKE1_1_, car1_.MODEL as MODEL1_1_, car1_.YEAR as YEAR1_1_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID
However, I want to instantiate a new transfer object EmployeeData using various data (employee + employee.address) (yes, I know this example is a bit contrived since we can get the address from the employee anyway, .. .but in real life, we might want other data from a JOIN with another table etc etc ... . I use the following HQL
Code:
emp = (List<EmployeeData>) session.createQuery("select new com.me.dbstuff.data.EmployeeData(a, a.address) from AbstractEmployee a").list();
This is what I see in the debug logs. How can I avoid all the extra SELECTs while still being able to instantiate the DTO EmployeeData object?
Thanks in Advance
Code:
Hibernate: /* select new com.me.dbstuff.data.EmployeeData(a, a.address) from AbstractEmployee a */ select abstractem0_.ID as col_0_0_, abstractem0_.ADDRESS as col_1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?
Hibernate: /* load com.me.dbstuff.data.AbstractEmployee */ select abstractem0_.ID as ID2_1_, abstractem0_.ADDRESS as ADDRESS2_1_, abstractem0_.car_ID as car5_2_1_, abstractem0_.NAME as NAME2_1_, abstractem0_2_.CE_HOURLYRATE as CE1_4_1_, abstractem0_3_.FE_ANNUALSALARY as FE1_5_1_, abstractem0_.DTYPE as DTYPE2_1_, car1_.ID as ID1_0_, car1_.LICENSEPLATEID as LICENSEP2_1_0_, car1_.MAKE as MAKE1_0_, car1_.MODEL as MODEL1_0_, car1_.YEAR as YEAR1_0_ from ABSTRACTEMPLOYEE abstractem0_ left outer join BASIC_EMPLOYEE abstractem0_1_ on abstractem0_.ID=abstractem0_1_.BASIC_EMPLOYEE_ID left outer join CONTRACT_EMPLOYEE abstractem0_2_ on abstractem0_.ID=abstractem0_2_.CONTRACT_EMPLOYEE_ID left outer join FULLTIME_EMPLOYEE abstractem0_3_ on abstractem0_.ID=abstractem0_3_.FULLTIME_EMPLOYEE_ID left outer join CAR car1_ on abstractem0_.car_ID=car1_.ID where abstractem0_.ID=?