【发布时间】:2021-09-10 11:41:00
【问题描述】:
拥有这个实体:
User.java:
@Entity
@NoArgsConstructor
@Getter
@Setter
public class User {
@Id
private int id;
private String username;
@OneToMany(mappedBy = "owner")
@MapKey(name = "friend_id")
private Map<User, Friendship> friends = new HashMap<>();
}
友谊:
@Entity
@Data
//@IdClass(Friendship.class)
public class Friendship implements Serializable {
@Id
private int owner_id;
@Id
private int friend_id;
private String level;
@ManyToOne
@MapsId("owner_id")
private User owner;
@ManyToOne
@MapsId("friend_id")
private User friend;
}
如果我想使用两个或更多主键,我必须有@IdClass 或@EmbeddedId。但如上所示,我可以省略其中任何一个,只声明两个主键(这就是我的意思是“编译”)。所以问题是,为什么还要费心使用这些注释中的任何一个,而只是声明更多的键?
生成的表:
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| owner_id | int | NO | PRI | NULL | |
| friend_id | int | NO | PRI | NULL | |
| level | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
【问题讨论】:
-
“编译”和“拥有多个主键”是什么意思?您的研究表明为什么存在 PK 以及 PK 或备用密钥是什么以及“使用 @IdClass 明确声明它的好处”? How to Ask
-
@philipxy 如果我想使用 两个 或更多主键,我必须有
@IdClass或@EmbeddedId。但如上所示,我可以省略任何一个,只声明两个主键(这就是我的意思是“编译”)。所以问题是,为什么还要费心使用这些注释中的任何一个,而只是声明更多的键? -
请通过编辑而非 cmets 进行澄清。 PS只能有一个PK。可以有多个“候选”/唯一键——其中一个可以是 PK。但是构成复合 PK 的 2 列中的任何一个都不是 PK 的候选者。两者都不唯一地确定一个实体。阅读有关键的信息。请在考虑发布问题之前进行研究。
-
这个实体生成的表的定义,有 2个主键(
owner_id和friend_id)。所以我没看懂你的说法,*只能有一个PK。 -
该表没有 2 个 PK。它有 2 个 FK,列的值是其他地方的 PK。
标签: spring hibernate primary-key composite-primary-key