2015-11-30 105 views
0

我有很多一對多JPA:額外的屬性映射多對多關係

employeeId skillSetId numberOfYears 
10   101   2 

我是新來的JPA,無法定義實體EmployeeSkillSet表之間的關係,附加列numberOfYears每個關係與關係。我應該爲Employee_SkillSet表定義一個新的實體類嗎?或者我可以在EmployeeSkillSet課程中定義多對多關係?我在哪裏指定numberOfYears列?

編輯:似乎重複,但我明確要求使用@IdClass,其中一個實體是@MappedSuperclass,因此必須同時定義ID實例和被引用實體對象。

回答

1

由於您需要爲元組(Employee,SkillSet)添加一個字段,因此您必須創建另一個實體。

@Entity 
public class Employee implements Serializable { 
    private @Id Long id; 

    @OneToMany(mappedBy="employee") 
    private List<EmployeeSkillSet> skillSets; 
} 

@Entity 
public class SkillSet implements Serializable { 
    private @Id Long id; 
} 

@Entity 
public class EmployeeSkillSet implements Serializable { 
    private @Id Long id; 
    private @ManyToOne Employee employee; 
    private @ManyToOne SkillSet skillSet; 
    private @Basic int numberOfYears; 
} 

當然你也可以選擇使用@IdClass,使(「僱員」,「技能」)的EmployeeSkillSet像這樣的主鍵:

@Entity @IdClass(EmployeeSkillSet.Key.class) 
public class EmployeeSkillSet implements Serializable { 

    private @Id @ManyToOne Employee employee; 
    private @Id @ManyToOne SkillSet skillSet; 
    private @Basic int numberOfYears; 

    public static class Key implements Serializable { 
     private Long employee; // plus getter+setter 
     private Long skillSet; // plus getter+setter 
     // plus hashCode, equals 
    } 
} 
+0

我在EmployeeSkillSet中沒有'id'列,我將如何定義實體上的主鍵? – sidgate

+0

我已更新我的答案以顯示'@ IdClass'選項。 –

+0

謝謝。我的用例在關係中的一個實體是「@ MappedSuperClass」時很複雜,所以不能在EmployeeSkillSet中定義它。相反,我正在定義ID列和@ManyToOne。請參考我的另一個問題http://stackoverflow.com/questions/34013489/jpa-mapping-manytomany-relationship-refers-to-incorrect-column-name/34013650#34013650 – sidgate

1

雖然可以使用@ManyToMany註釋爲了模擬多對多關係,更好地考慮性能原因定義了兩對多關係。

您將需要4件文物,有

  • 僱員實體
  • 技能實體
  • EmployeeSkillSet關聯實體(在這裏你可以指定numberOfYears列)
  • EmployeeSkillSetPK(用於EmployeeSkillSet關聯實體的主鍵)

代碼會是這樣的

僱員

package <your_package>; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

/** 
* 
*/ 
@Entity 
@Table(name="EMPLOYEE") 
public class Employee implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="EMPLOYEEID") 
    private int id; 

    // Rest of columns and getter and setters for all 
} 

技能

package <your_package>; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

/** 
* 
*/ 
@Entity 
@Table(name="SKILLSET") 
public class SkillSet implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="SKILLSETID") 
    private int id; 

    // Rest of columns and getter and setters for all 
} 

EmployeeSkillSetPK

/** 
* 
*/ 
package <your_package>; 

import java.io.Serializable; 

import javax.persistence.Embeddable; 

/** 
* 
*/ 
@Embeddable 
public class EmployeeSkillSetPK implements Serializable { 

    @ManyToOne 
    private Employee emp; 

    @ManyToOne 
    private SkillSet sk; 
    /** 
    * @return the employee 
    */ 
    public Employee getEmployee() { 
     return emp; 
    } 
    /** 
    * @param employee the employee to set 
    */ 
    public void setEmployee(Employee employee) { 
     this.employee = employee; 
    } 
    /** 
    * @return the sk 
    */ 
    public SkillSet getSkillSet() { 
     return sk; 
    } 
    /** 
    * @param sk the sk to set 
    */ 
    public void setSkillSet(SkillSet sk) { 
     this.sk = sk; 
    } 

    public boolean equals(Object o) { 
     if (this == o) { 
      return true; 
     } 

     if (o == null || getClass() != o.getClass()) { 
      return false; 
     } 

     EmployeeSkillSetPK that = (EmployeeSkillSetPK) o; 

     if (employee != null ? !employee.equals(that.employee) : that.employee != null) { 
      return false; 
     } 
     if (sk != null ? !sk.equals(that.sk) : that.sk != null) { 
      return false; 
     } 

     return true; 
    } 

    public int hashCode() { 
     int result; 
     result = (employee != null ? employee.hashCode() : 0); 
     result = 31 * result + (sk != null ? sk.hashCode() : 0); 
     return result; 
    } 
} 

EmployeeSkillSet

這是JPA 1.0,我現在不能測試的代碼,但它應該工作。

請注意,我自己寫了表名和列名。根據需要調整它。

+0

感謝詳細的代碼。我們可以使用'@ IdClass'而不是'@ EmbeddedId'嗎? – sidgate

+0

我認爲是可能的,IdClass可因爲JPA 1.0(http://docs.oracle.com/javaee/5/api/javax/persistence/IdClass.html)。我現在沒有使用IdClass的示例,但如果需要,我可以稍後在家中進行測試 –