为什么Hibernate不生成多对多关系表的主键?

时间:2016-03-25 02:48:17

标签: java mysql hibernate many-to-many

我有一个简单的多对多表。一个术语可以属于多个类别,一个类别可以分配给多个术语。

Term.java

@Entity
public class Term implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @NotNull
    @Size(min = 1, max = 100)
    private String name;

    @ManyToMany(mappedBy="terms")
    private List<Category> categories = new ArrayList<Category>();

    ...
    // getters and setters
}

Category.java

@Entity
public class Category implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @NotNull
    @Size(min = 1, max = 255)
    private String name;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private List<Term> terms = new ArrayList<>();

   // getters and setters
}

然而,生成的交集表&#34;&#34;不包含主键,如下所示:

MariaDB [wordDS]>describe Category_Term;
+---------------+------------+------+-----+---------+-------+
| Field         | Type       | Null | Key | Default | Extra |
+---------------+------------+------+-----+---------+-------+
| categories_id | bigint(20) | NO   | MUL | NULL    |       |
| terms_id      | bigint(20) | NO   | MUL | NULL    |       |
+---------------+------------+------+-----+---------+-------+

不应该总是需要复合键作为主键,并且应该由Hibernate自动创建吗?如何自动创建?

3 个答案:

答案 0 :(得分:6)

使用Set代替List来强制执行唯一性。 Hibernate将生成主键。

@ManyToMany(mappedBy="terms")
private Set<Category> categories = new HashSet<Category>();

/* ... */

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Term> terms = new HashSet<>();

答案 1 :(得分:0)

List更改为Set。这样Hibernate将为连接表生成主键。

答案 2 :(得分:0)

我用过:

for Book entity

@ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "Book_Author", joinColumns = { @JoinColumn(name = "Author_Id",nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "Book_Id", nullable = false) })
Set<Author> getAuthors(){
..................
}

作者实体

@ManyToMany(cascade = CascadeType.ALL, mappedBy = "authors")
Set<Author> getBooks(){
..................
}

它在postgre中生成:

create table book_author
(
    bus_id integer not null
        constraint fks1cidrw188x56mfa802xfj23j
            references book,
    equipment_id integer not null
        constraint fkm0ll4he65a8gfasp0sqg5tp2l
            references author,
    constraint book_author_pkey
        primary key (author_id, book_id)
)
;

因此,将为两列生成主键。