当前位置: 首页 > 面试题库 >

使用主键联接列进行一对一映射

端木志诚
2023-03-14
问题内容

我使用主键联接列(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。这样做会做得更好,因为相应的员工已经加载了第一个查询。

如果您在B)中应用我的建议,该信息应该会消失。

B)默认情况下,JPA中渴望一对一关联。使其变得懒惰:

@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private Employee empl;

但是,请记住此处描述的一对一关联的行为。如果Hibernate无法确定是否存在一对一关系的代理对象null,则无论如何将执行附加查询以检查它。

为了克服这个问题,如果empl每个参数都是强制性的EmployeeDetail(并且在您的用例中是必需的,那么没有该员工就不能存在一个员工详细信息),然后在关联映射中进行指示:

@OneToOne(fetch = FetchType.LAZY, optional = false)
@PrimaryKeyJoinColumn
private Employee empl;

这样,Employee当加载EmployeeDetail实体实例而employee根本不查询表时,Hibernate将使代理仅包含id 。



 类似资料:
  • 我想使用Hibernate条件语言编写此查询。我对Hibernate很陌生,无法将此查询转换为条件形式。我参考了很多关于 SO 的答案,但就我而言,我在不同的列上使用内部连接而不是主键/外键列。我提到了这个,但仍然不能正确。

  • 我有两个不同的表,Person表和Employee表。我需要这两者之间的一一对应。Employee表的emp_id引用Person表的PERSON_ID。我需要一些帮助来编写使用注释的映射 persons.java

  • 我正在处理遗留系统,需要从数据库中读取一些信息。下面是表格关系 供应商(vendorid-pk,vendorEid,name) VendorContactBridge(bridgeid-pk,vendorEid,contactEid) 联系人(contactid-pk,contactEid,phone) vendorEid和contactEid不是表的主键,但用作联接表VendoContactBr

  • 我试图在Hibernate中的两个表之间创建一对一的单向主键关系。我使用xml Maaping,下面是我的java POJO类和它们各自的。hbm文件。 储物柜POJO类 locker.hbm.xml 下面是我用来保存student和locker对象的主类。

  • 1. 前言 本节课程和大家一起聊聊关联映射。通过本节课程的学习,你将了解到: 什么是关联映射; 如何实现一对一关联映射。 2. 关联映射 关系数据库中的数据以表为家,一张表一个家,一个家住一类数据。众多表组成关系型社区,关系型社区群体中的数据关系通过主外键方式描述。 表与表之间的数据根据彼此的关系可分为: 一对一关系: 如老公表和老婆表的关系; 一对多关系: 如用户表和银行账号表关系; 多对一关系