2014-02-25 128 views
4

我想知道hibernate是否支持使用字段和組件類型的複合主鍵。所以我有一個@Embeddable組件類型,我想將它作爲主鍵與另一個列一起作爲組合主鍵。Hibernate複合主鍵使用@Embedded和@Id

所以我的表「DEPT_HISTORY」有複合主鍵(GROUP_DEPT,DEPTID,EFFDT)。我將GROUP_DEPT和DEPTID作爲@Embeddable組件類型映射到Department類。

@Embeddable public class Department implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private String departmentGroup; 

    private String departmentId; 

    public String getDepartmentGroup() { 
     return departmentGroup; 
    } 

    public void setDepartmentGroup(String departmentGroup) { 
     this.departmentGroup = departmentGroup; 
    } 

    public Department withDepartmentGroup(String departmentGroup) { 
     setDepartmentGroup(departmentGroup); 
     return this; 
    } 

    public String getDepartmentId() { 
     return departmentId; 
    } 

    public void setDepartmentId(String departmentId) { 
     this.departmentId = departmentId; 
    } 

    public Department withDepartmentId(String departmentId) { 
     setDepartmentId(departmentId); 
     return this; 
    } 

    @Override 
    public String toString() { 
     return Objects.toStringHelper(this).add("departmentGroup", getDepartmentGroup()) 
       .add("departmentId", getDepartmentId()).toString(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof Department)) { 
      return false; 
     } 
     Department other = (Department) obj; 

     return Objects.equal(getDepartmentGroup(), other.getDepartmentGroup()) 
       && Objects.equal(getDepartmentId(), other.getDepartmentId()); 

    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(getDepartmentGroup(), getDepartmentId()); 
    } 

} 

我使用上面的GROUP_DEPT,DEPTID和EFFDT如下映射覆合主鍵。 hibernate是否支持這個。我有類似的類,它的工作原理,但由於某種原因失敗,這個類與「引起:org.hibernate.AnnotationException:com.blah.blah.component.Department不得有@Id屬性時使用@EmbeddedId:com .blah.blah.entity.DepartmentHistory.department

@Entity @Table(name = "dept_history") public class DepartmentHistory implements Serializable { 

    private static final long serialVersionUID = 1L; 
    private static final String DATETIME_FORMAT = "MM-dd-yyyy HH:mm:ss ZZ"; 
    protected static final DateTimeFormatter DATE_FORMAT = DateTimeFormat.forPattern(DATETIME_FORMAT); 

    @Id 
    @Embedded 
    @AttributeOverrides({ 
      @AttributeOverride(name = "departmentGroup", column = @Column(name = "GROUP_DEPT", nullable = false)), 
      @AttributeOverride(name = "departmentId", column = @Column(name = "DEPTID", nullable = false)) }) 
    private Department department; 

    @Id 
    @Column(name = "EFFDT", nullable = false) 
    @Temporal(TemporalType.TIMESTAMP) 
    private Calendar effectiveDate; 

    @Column(name = "DESCR", nullable = false) 
    private String description; 

    @Column(name = "MANAGER_ID", nullable = false) 
    private String managerId; 

    public Department getDepartment() { 
     return department; 
    } 

    public void setDepartment(final Department department) { 
     this.department = department; 
    } 

    public DepartmentHistory withDepartment(final Department department) { 
     setDepartment(department); 
     return this; 
    } 

    public Calendar getEffectiveDate() { 
     return effectiveDate; 
    } 

    public void setEffectiveDate(final Calendar effectiveDate) { 
     this.effectiveDate = effectiveDate; 
    } 

    public DepartmentHistory withEffectiveDate(final Calendar effectiveDate) { 
     setEffectiveDate(effectiveDate); 
     return this; 
    } 

    public DateTime readEffectiveDateAsDateTime() { 
     return calendarToDateTime(effectiveDate); 
    } 

    public void writeEffectiveDateAsDateTime(final DateTime effectiveDate) { 
     this.effectiveDate = dateTimeToCalendar(effectiveDate); 
    } 

    public DepartmentHistory withEffectiveDateAsDateTime(final DateTime effectiveDate) { 
     writeEffectiveDateAsDateTime(effectiveDate); 
     return this; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(final String description) { 
     this.description = description; 
    } 

    public DepartmentHistory withDescription(final String description) { 
     setDescription(description); 
     return this; 
    } 

    public String getManagerId() { 
     return managerId; 
    } 

    public void setManagerId(final String managerId) { 
     this.managerId = managerId; 
    } 

    public DepartmentHistory withManagerId(final String managerId) { 
     setManagerId(managerId); 
     return this; 
    } 

    @Override 
    public String toString() { 
     return Objects.toStringHelper(this).add("department", getDepartment()) 
       .add("effectiveDate", DATE_FORMAT.print(readEffectiveDateAsDateTime())) 
       .add("description", getDescription()).add("managerId", getManagerId()).toString(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof DepartmentHistory)) { 
      return false; 
     } 
     DepartmentHistory other = (DepartmentHistory) obj; 

     return Objects.equal(getDepartment(), other.getDepartment()) 
       && Objects.equal(getEffectiveDate(), other.getEffectiveDate()); 

    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(getDepartment(), getEffectiveDate()); 
    } 

} 

我可以結合一個@Embeddable和其他領域的使用將在@Embedded和現場@Id屬性的複合主鍵。我不想做( GROUP_DEPT,DEPTID,EFFDT)作爲@EmbeddedId,因爲這樣的組件類型沒有意義,我不想創建一個類,這並不意味着我的域中任何東西只是用作組合主鍵。只是(GROUP_DEPT,DEPTID)作爲部門很有意義。非常感謝。

回答

1

根據規範,您應該使用和@EmbeddedId或@IdClass當您使用組合鍵。

如果從屬實體類除了具有 主鍵屬性的那些對應於父的主鍵或如果父 具有複合主鍵,嵌入式ID或ID類必須使用 指定依賴實體的主鍵。這不是 父母實體和從屬實體都必須使用嵌入的 id或兩者都使用id類來表示 父母具有組合鍵時的複合主鍵。

問題是:

我映射使用GROUP_DEPT,DEPTID以上 和EFFDT下面如下複合主鍵。 hibernate是否支持這個。

是的hibernate支持,但你應該使用@EmbeddedId,我知道這需要創建一個新的類來處理密鑰,但需要做的據我所知。

+0

感謝您的回覆。我沒有在這裏實施任何繼承,所以沒有父母和依賴實體。例如,我有類似的類。位置和位置歷史記錄,其中組件類型位置(GROUP_LOCATION,LOCATION)和EFFDT作爲實體location_history中的字段。我用完全相同的方式映射它,它工作得很好。只是這個特殊的班級似乎沒有工作,我不知道爲什麼。 – user290870

+0

只是一個問題,當你嘗試使用EntityManager查找方法檢索基於某個鍵的對象時,模型是否有效? – Koitoer

+0

當Spring嘗試實例化bean時,此模型失敗,出現上述異常。然而,我有一個類似的位置模型,當我做Location Location = new Location()。withLocationGroup(「TEST」)。withLocationId(「100」); List locationHistories = locationHistoryDao.getLocationHistoryById(location);在道,我使用標準API來獲得結果 – user290870