我正在创建一种社交网络,我的用户可以关注其他用户。所以我有一个像:
这样的实体@Entity
public class FollowedUser{
@ManyToOne
private User user;
@ManyToOne
private User followedUser;
//more fields
...
}
我不能拥有ManyToMany关系,因为我的FollowedUser实体中有更多字段。现在,我的问题是:
答案 0 :(得分:1)
1。我建议使用代理键。我发现将记录的数据库标识与其业务标识分开是有帮助的。如果这两个概念是混合的,那么对它们进行正确建模并稍后重新构造它们可能很麻烦。你引用了一些很好的答案,所以你可能已经意识到了主要的上行和下行,这里不需要重复它们。还有一点是,您可以依赖UUID
这样的代理键来正确实施equals
和hashCode
。实现复合键的那些可以很好地兼顾集合和数据库,这可能很棘手。
对于您的用例,用户之间的连接可以被视为自己的实体,并具有自动生成的代理PK。您可以在数据库中强制实施业务键属性的唯一性,请参阅第3页。
2。 AFAIK,在EmbeddedId
和IdClass
之间做出决定主要是品味问题。我更喜欢
IdClass
,因为它可以避免在查询id属性时添加导航:
... WHERE a.id.attribute = :att
与EmbeddedId
vs。
... WHERE a.attribute = :att
与IdClass
我没有发现你链接的论点6令人信服。复合键往往由实体的最具特征的属性组成。要将它们隐藏在另一个类中,因为它们碰巧被用作数据库密钥对我来说似乎很尴尬。
3。唯一索引看起来是保证属性组合唯一性的好方法。您可能需要阅读this answers, there is a small example。
如果您尚未使用JPA 2.1,则可能需要使用唯一约束,explained here。