2010-03-03 30 views
4
一個多一對多關係的複合鍵

我有以下情況:使用在JPA

  • 用戶對象有一組Permission對象(Set<Permission>
  • 每個用戶可以有零個或多個權限
  • 權限對象有三個字段
  • 權限的三個字段組成該權限的複合鍵 。
  • 由於這個原因,我們需要在每個權限的DB中確切地使用 一個實例。每個用戶可能有 具有相同的權限。
  • 用戶對象因此與權限具有 多對多關係。

問題是:在這種情況下,我如何讓Permission實體成爲自己的複合鍵?我特別有興趣在這種多對多關係的背景下做到這一點。

任何想法?

回答

4

一個權限對象有三個字段

權限的三個字段了彌補該複合鍵

兩個屬性和化合物主鍵共享相同的列

所以你的問題看起來像這個

@Entity 
public class Permission { 

    private PermissionId permissionId; 

    private Integer field1; 
    private Integer field2; 
    private Integer field3; 

    // required no-arg constructor 
    public Permission() {} 

    public Permission(Integer field1, Integer field2, Integer field3) { 
     this.field1 = field1; 
     this.field2 = field2; 
     this.field3 = field3; 

     setPermissionId(new PermissonId(Integer field1, Integer field2, Integer field3)); 
    } 

    @EmbeddedId 
    public PermissionId getPermissionId() { 
     return this.permissionId; 
    } 

    @Column(name="FIELD_1", insertable=false, updatable=false) 
    public Integer getField1() { 
     return this.field1; 
    } 

    @Column(name="FIELD_2", insertable=false, updatable=false) 
    public Integer getField2() { 
     return this.field2; 
    } 

    @Column(name="FIELD_3", insertable=false, updatable=false) 
    public Integer getField3() { 
     return this.field3; 
    } 

    @Embeddable 
    public static class PermissionId implements Serializable { 

     private Integer field1; 
     private Integer field2; 
     private Integer field3; 

     // required no-arg constructor 
     public PermissionId() {} 

     public PermissionId(Integer field1, Integer field2, Integer field3) { 
      this.field1 = field1; 
      this.field2 = field2; 
      this.field3 = field3; 
     } 

     @Column(name="FIELD_1", nullable=false) 
     public Integer getField1() { 
      return this.field1; 
     } 

     @Column(name="FIELD_2", nullable=false) 
     public Integer getField2() { 
      return this.field2; 
     } 

     @Column(name="FIELD_3", nullable=false) 
     public Integer getField3() { 
      return this.field3; 
     } 

     public boolean equals(Object o) { 
      if(o == null) 
       return false; 

      if(!(o instanceof PermissionId)) 
       return false; 

      final PermissionId other = (PermissionId) o; 

      if(!(getField1().equals(other.getField1()))) 
       return false; 

      if(!(getField2().equals(other.getField2()))) 
       return false; 

      if(!(getField3().equals(other.getField3()))) 
       return false; 

      return true; 
     } 

     // requered hashcode impl 
     public int hashcode() { 
      // code goes here  
     } 

    } 

} 

但不要忘了

由於多個屬性共享相同的列,你必須確定其中一個作爲插入=假,可更新=假。否則,Hibernate會抱怨一些錯誤。

而且

當你有一個複合主鍵,你必須建立自己的價值觀。 Hibernate不支持自動生成複合主鍵。

,如果你不喜歡這種方法,如上圖所示,你可以做以下的一個

@Entity 
@IdClass(PermissionId.class) 
public class Permission { 

    private Integer field1; 
    private Integer field2; 
    private Integer field3; 

    // required no-arg constructor 
    public Permission() {} 

    public Permission(Integer field1, Integer field2, Integer field3) { 
     this.field1 = field1; 
     this.field2 = field2; 
     this.field3 = field3; 
    } 

    @Id 
    @Column(name="FIELD_1", nullable=false) 
    public Integer getField1() { 
     return this.field1; 
    } 

    @Id 
    @Column(name="FIELD_2", nullable=false) 
    public Integer getField2() { 
     return this.field2; 
    } 

    @Id 
    @Column(name="FIELD_3", nullable=false) 
    public Integer getField3() { 
     return this.field3; 
    } 

    @Embeddable 
    public static class PermissionId implements Serializable { 

     private Integer field1; 
     private Integer field2; 
     private Integer field3; 

     // required no-arg constructor 
     public PermissionId() {} 

     public PermissionId(Integer field1, Integer field2, Integer field3) { 
      this.field1 = field1; 
      this.field2 = field2; 
      this.field3 = field3; 
     } 

     @Column(name="FIELD_1") 
     public Integer getField1() { 
      return this.field1; 
     } 

     @Column(name="FIELD_2") 
     public Integer getField2() { 
      return this.field2; 
     } 

     @Column(name="FIELD_3") 
     public Integer getField3() { 
      return this.field3; 
     } 

     public boolean equals(Object o) { 
      if(o == null) 
       return false; 

      if(!(o instanceof PermissionId)) 
       return false; 

      final PermissionId other = (PermissionId) o; 

      if(!(getField1().equals(other.getField1()))) 
       return false; 

      if(!(getField2().equals(other.getField2()))) 
       return false; 

      if(!(getField3().equals(other.getField3()))) 
       return false; 

      return true; 
     } 

     // requered hashcode impl 
     public int hashcode() { 
      // code goes here  
     } 

    } 

} 

問候,