は難しいことではありません。
マッピングは次のようになりますので、複合識別子が2つの数値列の外に構築されています:
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'があって親に戻っていれば、それは単純にマップされます(そしてChildの"親 "関係フィールドはCHILDの2つのFK列を与えます表)。 –