2010-03-03 52 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  
     } 

    } 

} 

问候,