Как сделать составной первичный ключ с помощью Hibernate (аннотация many-to-many)?

Рейтинг: 3Ответов: 1Опубликовано: 14.09.2014

Здравствуйте. Подскажите пожалуйста как правильно делается составной первичный ключ с помощью Hibernate (в классе UserRole, который соответствует таблице user_role). Схема выглядит так:

CREATE TABLE user (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  name varchar(45) NOT NULL,
  password varchar(60) NOT NULL,
  enabled tinyint(4) NOT NULL DEFAULT '1',
  login varchar(60) NOT NULL,
  birthdate Date NOT NULL,
  address varchar(60),
  tel varchar(60),
  surname varchar(60) NOT NULL,
  email varchar(60) NOT NULL,
  confirmPassword varchar(60) NOT NULL,
  comment varchar(400),
  PRIMARY KEY (id)
);

CREATE TABLE role (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  name varchar(45) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE user_role (
  user_id bigint(20) NOT NULL,
  role_id bigint(20) NOT NULL,
  PRIMARY KEY (user_id, role_id),
  CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES user (id),
  CONSTRAINT fk_role FOREIGN KEY (role_id) REFERENCES role (id)
);

Если делаю так:

@Entity
@Table(name = "user_role")
public class UserRole {
    @Id
    @GeneratedValue
    @Column(name="user_id")
    private long idUser;

    @Id
    @GeneratedValue
    @Column(name="role_id")
   private long idRole;
  //геттеры, сеттеры
}

тогда в таблице user_role первичным ключем становится только role_id. Когда так делаю:

@Entity
@Table(name = "user_role")
public class UserRole {

 private long idUser;
 private long idRole;
 @Id
    @GeneratedValue
    @AttributeOverrides({
            @AttributeOverride(name = "idUser",
                    column = @Column(name="user_id")),
            @AttributeOverride(name = "idRole",
                    column = @Column(name="role_id"))
    })
    ...
    }

, то в таблице user_role создается аж 4 поля: idUser, idRole, user_id, role_id и первичным ключем становится только idUser.

Вот еще классы User и Role:

@Entity
@Table(name = "user")
public class User implements Serializable{

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String surname;
    @Column(columnDefinition = "enum('male','female')")
    @Enumerated(EnumType.STRING)
    private Gender gender = Gender.male;
    private Date birthdate;
    private String address;
    private String tel;
    private String email;
    //@Column(name = "login", unique = true, nullable = false)
    private String login;
    private String password;
    private String confirmPassword;
    private boolean enabled;
    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;
    private String comment;

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name="user_role",
            joinColumns={@JoinColumn(name="user_id")},
            inverseJoinColumns={@JoinColumn(name="role_id")})
    private Collection<Role> roles;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Collection<Role> getRoles() {
        return roles;
    }

    public void setRoles(Collection<Role> roles) {
        this.roles = roles;
    }
}

@Entity
    @Table(name = "role")
    public class Role {
        @Id
        @GeneratedValue

        private long id;
        private String name;
        @ManyToMany(mappedBy="roles")
        private Collection<User> users;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Collection<User> getUsers() {
            return users;
        }

        public void setUsers(Collection<User> users) {
            this.users = users;
        }
    }

Ответы

▲ 1

Необходимо создать дополнительный класс, содержащий все необходимые первичные ключи и пометить этот класс аннотацией @Embeddable, а затем в классе User обьявить поле этого класса с аннотацией @EmbeddedId