我使用主键联接列(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; .................... }
有人可以说明执行以下查询会话时的原因吗。createQuery(“ from Employee”)。list();
A)执行类似2),3)和4)的联接查询以从employeedetail中获取数据?为什么不使用雇员对象中的employeeid值直接从employeedetail表中获取数据而不进行联接?
1) Hibernate: select employee0_.employee_id as employee1_0_, employee0_.birth_date as birth_da2_0_, employee0_.cell_phone as cell_pho3_0_, employee0_.firstname as firstnam4_0_, employee0_.lastname as lastname5_0_ from employee employee0_ 2) Hibernate: select employeede0_.employee_id as employee1_1_0_, employeede0_.city as city2_1_0_, employeede0_.country as country3_1_0_, employeede0_.state as state4_1_0_, employeede0_.street as street5_1_0_, employee1_.employee_id as employee1_0_1_, employee1_.birth_date as birth_da2_0_1_, employee1_.cell_phone as cell_pho3_0_1_, employee1_.firstname as firstnam4_0_1_, employee1_.lastname as lastname5_0_1_ from employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id where employeede0_.employee_id=? 3) Hibernate: select employeede0_.employee_id as employee1_1_0_, employeede0_.city as city2_1_0_, employeede0_.country as country3_1_0_, employeede0_.state as state4_1_0_, employeede0_.street as street5_1_0_, employee1_.employee_id as employee1_0_1_, employee1_.birth_date as birth_da2_0_1_, employee1_.cell_phone as cell_pho3_0_1_, employee1_.firstname as firstnam4_0_1_, employee1_.lastname as lastname5_0_1_ from employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id where employeede0_.employee_id=? 4) Hibernate: select employeede0_.employee_id as employee1_1_0_, employeede0_.city as city2_1_0_, employeede0_.country as country3_1_0_, employeede0_.state as state4_1_0_, employeede0_.street as street5_1_0_, employee1_.employee_id as employee1_0_1_, employee1_.birth_date as birth_da2_0_1_, employee1_.cell_phone as cell_pho3_0_1_, employee1_.firstname as firstnam4_0_1_, employee1_.lastname as lastname5_0_1_ from employeedetail employeede0_ left outer join employee employee1_ on employeede0_.employee_id=employee1_.employee_id where employeede0_.employee_id=?
B)同样,对于查询session.createQuery(“ from EmployeeDetail”)。list();
why employee info is fetched as per below select queries instead of being proxied? Hibernate: select employeede0_.employee_id as employee1_1_, employeede0_.city as city2_1_, employeede0_.country as country3_1_, employeede0_.state as state4_1_, employeede0_.street as street5_1_ from employeedetail employeede0_ Hibernate: select employee0_.employee_id as employee1_0_0_, employee0_.birth_date as birth_da2_0_0_, employee0_.cell_phone as cell_pho3_0_0_, employee0_.firstname as firstnam4_0_0_, employee0_.lastname as lastname5_0_0_ from employee employee0_ where employee0_.employee_id=? Hibernate: select employee0_.employee_id as employee1_0_0_, employee0_.birth_date as birth_da2_0_0_, employee0_.cell_phone as cell_pho3_0_0_, employee0_.firstname as firstnam4_0_0_, employee0_.lastname as lastname5_0_0_ from employee employee0_ where employee0_.employee_id=? Hibernate: select employee0_.employee_id as employee1_0_0_, employee0_.birth_date as birth_da2_0_0_, employee0_.cell_phone as cell_pho3_0_0_, employee0_.firstname as firstnam4_0_0_, employee0_.lastname as last`enter code here`name5_0_0_ from employee employee0_ where employee0_.employee_id=?
A)有点奇怪,而且Hibernate可以做得更好。但是,这是由于这样的事实:Employee加载急切EmployeeDetail,并且Hibernate希望避免额外的查询来为每个加载相应的雇员EmployeeDetail。这样做会做得更好,因为相应的员工已经加载了第一个查询。
Employee
EmployeeDetail
如果您在B)中应用我的建议,该信息应该会消失。
B)默认情况下,JPA中渴望一对一关联。使其变得懒惰:
@OneToOne(fetch = FetchType.LAZY) @PrimaryKeyJoinColumn private Employee empl;
但是,请记住此处描述的一对一关联的行为。如果Hibernate无法确定是否存在一对一关系的代理对象null,则无论如何将执行附加查询以检查它。
null
为了克服这个问题,如果empl每个参数都是强制性的EmployeeDetail(并且在您的用例中是必需的,那么没有该员工就不能存在一个员工详细信息),然后在关联映射中进行指示:
empl
@OneToOne(fetch = FetchType.LAZY, optional = false) @PrimaryKeyJoinColumn private Employee empl;
这样,Employee当加载EmployeeDetail实体实例而employee根本不查询表时,Hibernate将使代理仅包含id 。
employee