2016-08-01 4 views
1

주변, JPA (2)하는 일대일 관계또는 자연 키을 갖는 엔티티, 나는 수 없었다로 모델링하는 방법에 대한 많은 정보가 있지만 부모 테이블에 자연 키가있는 일대일 관계 등 두 가지 상황이 모두있는 상황을 모델링하는 방법에 대한 명확하고 간단한 대답을 찾으십시오. 분명히 내가 그런 튜토리얼을 놓친 것일 수도있다. 그렇다면 나를 가리켜 주면 답이 될 수도 있습니다."상위"테이블에 복합 PK가있는 경우 JPA에서 일대일 관계를 모델링하는 방법은 무엇입니까?

그리고 JPA와 I와 같은 멍청이들과 같이 가장 기본적인 모델보다 약간 더 필요한 순간이 있습니다. 벽을 빨리 찰 수 있습니다. 따라서

, 다음 DB 모델 고려 :

enter image description here

은 무엇 해당 JPA-주석 객체 모델이 될 것입니까? (나는 대답에 영향을 미치고 싶지 않기 때문에 시도한 것들을 남겨두고 있습니다 ...)

성능 권장 사항도 환영합니다 (예 : "일대 다 (one-to-many) , 등)! 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'을 가지고 있다면 간단히 매핑됩니다 (그리고 자식의 "부모"관계 필드는 자식의 2 개의 FK 컬럼을 제공합니다 표). –

답변

5

는 어렵지 않다. 매핑은 다음과 같습니다 있도록

복합 식별자는 두 개의 숫자 열에서 구축된다

@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; 
    } 
} 

그리고이 같은 아이 : 다음과 같이

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 = "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

감사합니다 블라드! 내가 원했던 것은 "parent"클래스의 멤버/속성 (예 : Employee)으로 자식 ('EmployeeDetails')에 대한 액세스 권한을 부여했습니다. 다음과 같은 것 :'public class Employee {... public EmployeeDetails getDetails() {...} ...' –

+1

업데이트 된 답변을 확인하십시오. –

+0

굉장 - 다시 한번 감사드립니다! –