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

why doesn't Hibernate generate primary key for many-to-many relationship table?

我有一个简单的多对多 table。一个Term可以属于多个Categories,一个Category可以分配给多个Terms。

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
}

但是,生成的交集 table "" 不包含主键,如下所示:

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 自动创建吗?我怎样才能自动创建它?

使用 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<>();

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

我用过:

对于图书实体

@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)
)
;

所以,主键是为两列一起生成的。