Использование составного ключа в отношениях многих ко многим в JPA - PullRequest
4 голосов
/ 03 марта 2010

У меня следующая ситуация:

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

Вопрос заключается в следующем: как в этой ситуации сделать объект разрешения отдельным составным ключом? Я особенно заинтересован в том, чтобы делать это в контексте этих отношений «многие ко многим».

Есть идеи?

1 Ответ

4 голосов
/ 04 марта 2010

Объект разрешения имеет три поля

Три поля Разрешения составляют составной ключ

Ключи свойств и составные первичные ключи имеют одни и те же столбцы

Итак, ваш вопрос выглядит так

@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     
        }

    }

}

Но не забудьте

Поскольку более одного свойства совместно используют один и тот же столбец , вы должны определить одно из них как inserttable = false, updatable = false. В противном случае 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     
        }

    }

}

С уважением,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...