映射复合键并不困难。
复合标识符建出来两种数值列的这样的映射如下所示:
Embeddable
public class EmployeeId implements Serializable {
private Long companyId;
private Long employeeId;
public EmployeeId() {
}
public EmployeeId(Long companyId, Long employeeId) {
this.companyId = companyId;
this.employeeId = employeeId;
}
public Long getCompanyId() {
return companyId;
}
public Long getEmployeeId() {
return employeeId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EmployeeId)) return false;
EmployeeId that = (EmployeeId) o;
return Objects.equals(getCompanyId(), that.getCompanyId()) &&
Objects.equals(getEmployeeId(), that.getEmployeeId());
}
@Override
public int hashCode() {
return Objects.hash(getCompanyId(), getEmployeeId());
}
}
父类,如下所示:
@Entity(name = "Employee")
public static class Employee {
@EmbeddedId
private EmployeeId id;
private String name;
@OneToOne(mappedBy = "employee")
private EmployeeDetails details;
public EmployeeId getId() {
return id;
}
public void setId(EmployeeId id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeDetails getDetails() {
return details;
}
public void setDetails(EmployeeDetails details) {
this.details = details;
}
}
而像这样的子:
@Entity(name = "EmployeeDetails")
public static class EmployeeDetails {
@EmbeddedId
private EmployeeId id;
@MapsId
@OneToOne
private Employee employee;
private String details;
public EmployeeId getId() {
return id;
}
public void setId(EmployeeId id) {
this.id = id;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
this.id = employee.getId();
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
而且一切正常:
doInJPA(entityManager -> {
Employee employee = new Employee();
employee.setId(new EmployeeId(1L, 100L));
employee.setName("Vlad Mihalcea");
entityManager.persist(employee);
});
doInJPA(entityManager -> {
Employee employee = entityManager.find(Employee.class, new EmployeeId(1L, 100L));
EmployeeDetails employeeDetails = new EmployeeDetails();
employeeDetails.setEmployee(employee);
employeeDetails.setDetails("High-Performance Java Persistence");
entityManager.persist(employeeDetails);
});
doInJPA(entityManager -> {
EmployeeDetails employeeDetails = entityManager.find(EmployeeDetails.class, new EmployeeId(1L, 100L));
assertNotNull(employeeDetails);
});
doInJPA(entityManager -> {
Phone phone = entityManager.find(Phone.class, "012-345-6789");
assertNotNull(phone);
assertEquals(new EmployeeId(1L, 100L), phone.getEmployee().getId());
});
代码可在GitHub。
父对象有复合PK等方面具有'@ IdClass'。 Child对象具有用'@ Id'和Parent引用标注的单个字段。不知道这是如何“非标准”。谁知道“T_CHILD_C_PK”是什么。你把FK放在一边或另一边,所以我必须假定它是P_NK_1和P_NK_2儿童 –
事实上,前面的图表不太清楚,谢谢。我已经用(希望)更清晰的图像更新了该帖子。父表(T_PARENT)具有由2个字段(PARENT_PK1,PARENT_PK2)组成的自然键,并且正由子表T_CHILD引用。 –
你的架构更加清晰了,但事实是,如果你只是有一个'@ OneToOne'在孩子回父那么简单映射(在儿童中的“父”关系场给出了孩子2个FK列表)。 –