1

我正在创建一种社交网络,并且我的用户可以关注其他用户。所以我有一个像这样的实体:

@Entity
public class FollowedUser{
    @ManyToOne
    private User user;

    @ManyToOne
    private User followedUser;

    //more fields

    ...
}

我不能有 ManyToMany 关系,因为我的 FollowedUser 实体中有更多字段。现在,我的问题是:

  1. 我应该使用复合键还是生成的 id(代理键)?我已阅读以下链接(123)关于建议使用代理键的主题,但我不知道它们是否适用于我的具体案例(我的复合键将由两个代理外键组成) . 同样在这里(4)它说“复合主键通常在从遗留数据库映射时出现”,所以我认为他们不鼓励。
  2. 如果我应该使用复合键,我不知道是否应该使用 @IdClass (这里推荐5)或 @EmbeddedId (这里推荐6)或任何其他选项。虽然我觉得没关系。
  3. 如果我应该使用代理键,我不知道如何仍然无法重复复合候选键。我在这里 ( 7 ) 阅读了有关唯一索引的信息,但我不知道这是否是解决该问题的正确方法。
4

1 回答 1

1

1.我推荐使用代理键。我发现将记录的数据库身份与其业务身份分开会很有帮助。如果这两个概念混合在一起,那么对它们进行正确建模并在以后对其进行重构可能会很麻烦。您参考了一些很好的答案,因此您可能知道主要的优点和缺点,无需在此重申。另外一点是,您可以依靠代理键UUID来正确实施。为复合键实现这些以很好地与集合和数据库一起使用可能会很棘手。equalshashCode

至于您的用例,用户之间的连接可以被视为它自己的实体,并具有自动生成的代理 PK。您可以强制数据库中业务关键属性的唯一性,请参阅 pt.3。

2. AFAIK,在EmbeddedId和之间做出决定IdClass主要是一个品味问题。我更喜欢 IdClass,因为它避免了在查询 id 属性时添加导航:

... WHERE a.id.attribute = :attEmbeddedIdvs。

... WHERE a.attribute = :attIdClass

我认为您链接 6 的论点没有说服力。复合键往往由实体的最具特征的属性组成。将它们隐藏在不同的类中,因为它们恰好被用作 DB 键对我来说似乎很尴尬。

3.唯一索引看起来是保证属性组合唯一性的好方法。您可能想阅读这个答案,有一个小例子

如果您尚未使用 JPA 2.1,您可能想要使用唯一约束,如此处所述

于 2014-06-30T13:08:40.120 回答