hibernate - one to one mapping using primary key join column -
i have employee , employee detail classes mapped (bi directional) using primary key join column (employee_id)
@entity @table(name="employee") public class employee { @id @generatedvalue @column(name="employee_id") private long employeeid; @column(name="firstname") private string firstname; @column(name="lastname") private string lastname; @column(name="birth_date") @temporal(value = temporaltype.date ) private date birthdate; @column(name="cell_phone") private string cellphone; @onetoone(mappedby="empl", cascade=cascadetype.all) private employeedetail employeedetail; ... } @table(name="employeedetail") public class employeedetail { @id @column(name="employee_id", unique=true, nullable=false) @generatedvalue(generator="gen") @genericgenerator(name="gen", strategy="foreign", parameters=@parameter(name="property", value="empl")) private long employeeid; @column(name="street") private string street; @column(name="city") private string city; @column(name="state") private string state; @column(name="country") private string country; @onetoone @primarykeyjoincolumn private employee empl; .................... }
can please clarify why when executing following query session.createquery("from employee").list();
a) join queries 2),3) , 4) executed fetch data employeedetail? why not directly fetch employeedetail table using employeeid value in employee object without join?
1) hibernate: select employee0_.employee_id employee1_0_, employee0_.birth_date birth_da2_0_, employee0_.cell_phone cell_pho3_0_, employee0_.firstname firstnam4_0_, employee0_.lastname lastname5_0_ employee employee0_ 2) hibernate: select employeede0_.employee_id employee1_1_0_, employeede0_.city city2_1_0_, employeede0_.country country3_1_0_, employeede0_.state state4_1_0_, employeede0_.street street5_1_0_, employee1_.employee_id employee1_0_1_, employee1_.birth_date birth_da2_0_1_, employee1_.cell_phone cell_pho3_0_1_, employee1_.firstname firstnam4_0_1_, employee1_.lastname lastname5_0_1_ employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id employeede0_.employee_id=? 3) hibernate: select employeede0_.employee_id employee1_1_0_, employeede0_.city city2_1_0_, employeede0_.country country3_1_0_, employeede0_.state state4_1_0_, employeede0_.street street5_1_0_, employee1_.employee_id employee1_0_1_, employee1_.birth_date birth_da2_0_1_, employee1_.cell_phone cell_pho3_0_1_, employee1_.firstname firstnam4_0_1_, employee1_.lastname lastname5_0_1_ employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id employeede0_.employee_id=? 4) hibernate: select employeede0_.employee_id employee1_1_0_, employeede0_.city city2_1_0_, employeede0_.country country3_1_0_, employeede0_.state state4_1_0_, employeede0_.street street5_1_0_, employee1_.employee_id employee1_0_1_, employee1_.birth_date birth_da2_0_1_, employee1_.cell_phone cell_pho3_0_1_, employee1_.firstname firstnam4_0_1_, employee1_.lastname lastname5_0_1_ employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id employeede0_.employee_id=?
b) also, query session.createquery("from employeedetail").list();
why employee info fetched per below select queries instead of being proxied? hibernate: select employeede0_.employee_id employee1_1_, employeede0_.city city2_1_, employeede0_.country country3_1_, employeede0_.state state4_1_, employeede0_.street street5_1_ employeedetail employeede0_ hibernate: select employee0_.employee_id employee1_0_0_, employee0_.birth_date birth_da2_0_0_, employee0_.cell_phone cell_pho3_0_0_, employee0_.firstname firstnam4_0_0_, employee0_.lastname lastname5_0_0_ employee employee0_ employee0_.employee_id=? hibernate: select employee0_.employee_id employee1_0_0_, employee0_.birth_date birth_da2_0_0_, employee0_.cell_phone cell_pho3_0_0_, employee0_.firstname firstnam4_0_0_, employee0_.lastname lastname5_0_0_ employee employee0_ employee0_.employee_id=? hibernate: select employee0_.employee_id employee1_0_0_, employee0_.birth_date birth_da2_0_0_, employee0_.cell_phone cell_pho3_0_0_, employee0_.firstname firstnam4_0_0_, employee0_.lastname last`enter code here`name5_0_0_ employee employee0_ employee0_.employee_id=?
a) little bit weird, , hibernate better. however, due fact employee
loaded eagerly in employeedetail
, , hibernate wants avoid additional queries load corresponding employee each employeedetail
. better because corresponding employees loaded first query.
this should disappear if apply advice in b).
b) default, one-to-one associations eager in jpa. make lazy:
@onetoone(fetch = fetchtype.lazy) @primarykeyjoincolumn private employee empl;
however, keep in mind behavior of one-to-one associations described here. if hibernate cannot determine whether proxied object in one-to-one relation exists or null
, additional query executed anyway check this.
to overcome this, if empl
mandatory each employeedetail
(and in use case, employee detail cannot exist without employee), indicate in association mapping:
@onetoone(fetch = fetchtype.lazy, optional = false) @primarykeyjoincolumn private employee empl;
this way hibernate make proxy containing employee
id when loading employeedetail
entity instances without querying employee
table @ all.
Comments
Post a Comment