2010-03-03 9 views
4

У меня следующая ситуация:Использование составного ключа в многие-ко-многим в JPA

  • Объект пользователя имеет набор объектов разрешений (Set<Permission>)
  • Каждый пользователь может иметь ноль или более Разрешения
  • A Объект Permission имеет три поля
  • Три поля разрешения составляют составной ключ для этого разрешения.
  • В результате этого мы хотим точно указать один экземпляр в БД каждого разрешения. Каждый пользователь может потенциально иметь такое же разрешение.
  • Объект User поэтому имеет отношение «0» к с разрешением «все-ко-многим» с разрешением.

Вопрос в следующем: как в этой ситуации я могу сделать объект 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  
     } 

    } 

} 

С уважением,

Смежные вопросы