复合主键是最好的解决方案 - Hibernate Spring

问题描述 投票:4回答:1

我正在使用Spring,Hibernate和JPA构建一个聊天应用程序,我想要两个表 - 聊天和消息。聊天将有许多消息,也包括id和user_first以及user_second。现在我正在使用复合主键,其中复合是user_first和user_second,id是唯一的自动增量:

public class ChatPK implements Serializable {
    protected int firstUser;

    protected int secondUser;
... 

@Entity
@IdClass(ChatPK.class)
@Table(name = "chats1")
public class Chat implements Serializable {
    @Id
    private int firstUser;

    @Id
    private int secondUser;

    @Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int id;
...

有没有更好的方法来做到这一点,为什么?

更新:聊天是两个人之间的唯一行,不能有两个用户相同的聊天。我想把我需要的所有消息以及拥有这些消息的两个用户,所以我可以将发送者ID放入hashmap键,将消息放入值。对于下面的回答,SessionId与我的桌面聊天不同,实现我想要的不同。

java spring hibernate composite-primary-key
1个回答
1
投票

不,这不是最好的。主键的主要作用是带来唯一性,次要的是快速访问。密钥也用于缓存,因此密钥的大小会降低您可以缓存的数量。制作复合ckey意味着你需要覆盖hashcode并且可能等于。你太复杂了。

显然,firstUsier Id和第二个用户ID不足以为聊天带来唯一性,因为您可以在同一个用户之间进行多次聊天会话。

我认为您应该将您的id重命名为“sessionID”,将其用作主键,并在主键之外的两个用户之间建立两个关系。

@Entity
@Table(name = "chats1")
public class Chat implements Serializable {
    @ManyToOne
    private User firstUser;

    @ManyToOne
    private User secondUser;

    @Id
    @Column(name = "sessionId")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int sessionId;
...

更新:问题变成了复合键的优点和缺点,这里已经详细讨论了Why are composite keys discouraged in hibernate?

© www.soinside.com 2019 - 2024. All rights reserved.