2016-08-01 1 views
1

周り、JPAで(2)、1対1の関係OR自然キーを持つエンティティが、私はできなかったにモデル化する方法についての情報がたくさんありますが親テーブルにナチュラルキーがある一対一の関係を明確にする/簡単な答えを見つけることができます。明らかに私はこのようなチュートリアルを欠場している可能性があります。もしそうなら、私に1つを指し示すことも答えになる可能性があります。「親」表に複合PKがある場合、JPAで1対1の関係をモデル化する方法はありますか?

そして、JPAやIなどのノブで何度も、最も基本的なモデルより少しだけ多くの時間を必要とするので、すぐに壁に衝突することができます。したがって

、以下のDBモデルを考慮:

enter image description here

はどう対応するJPA注釈付きオブジェクト・モデルでしょうか? (私は答えに影響を与えたくないので、試したことを皆さんに惜しみません...)

パフォーマンスの推奨も歓迎です、等)! following articleに示すように、複合キーのマッピング

おかげで、

+0

親オブジェクトには複合PKがあり、 '@ IdClass'もあります。 Childオブジェクトには、 '@ Id'とParent参照で注釈が付けられた単一のフィールドがあります。それがどのように「非標準的」なのかは分かりません。誰が "T_CHILD_C_PK"が何であるかを知っている。あなたはFKを一方または他方に置くので、それは子供のP_NK_1とP_NK_2であると仮定しなければなりません。 –

+0

実際、前の図は明らかではありませんでした。私は(うまくいけば)もっと鮮明な画像で投稿を更新しました。親テーブル(T_PARENT)は、2つのフィールド(PARENT_PK1、PARENT_PK2)で形成され、子テーブルT_CHILDによって参照される自然なキーを有する。 –

+0

あなたのスキーマは今よりはっきりしていますが、子に '@ OneToOne'があって親に戻っていれば、それは単純にマップされます(そしてChildの"親 "関係フィールドはCHILDの2つのFK列を与えます表)。 –

答えて

5

は難しいことではありません。

マッピングは次のようになりますので、複合識別子が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で利用可能です。

+0

おかげさまでVlad!私がほしいと思ったのは、 "親"クラス(あなたの例では 'Employee')のメンバ/プロパティで、子にアクセスできるようにしました(' EmployeeDetails')。何かのように: 'public class Employee {... public EmployeeDetails getDetails(){...} ...' –

+1

私の更新された答えをチェックしてください。 –

+0

恐ろしい - もう一度ありがとう! –

関連する問題