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

时间:2019-02-16 11:51:47

标签: java spring hibernate composite-primary-key

我正在用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放入哈希映射键中,并将消息放入值中。对于下面的问题,SessionId与我的表聊天没有什么不同,实现我想要的东西没有不同的方式。

1 个答案:

答案 0 :(得分:1)

不,这不是最好的。主键的主要作用是带来唯一性,辅助键是快速访问。密钥也用于缓存,因此密钥的大小将决定您可以缓存的数量。制作复合ckey意味着您需要覆盖哈希码,并且可能等于。您太复杂了。

显然,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?

对此进行了详细讨论