JPA/Hibernate和复合键

JPA/Hibernate和复合键,jpa,composite-primary-key,Jpa,Composite Primary Key,我遇到过一些SO讨论和其他帖子(例如,和),其中将复合主键与JPA一起使用被描述为可能避免的事情,或者由于遗留数据库的需要,或者被描述为具有“毛茸茸的”角落案例。既然我们从头开始设计一个新的数据库,并且没有任何遗留的问题需要考虑,那么我们建议它还是更安全的,以避免具有 JPA < /强>的复合主键( Hibernate < /强>或 Eclipse >> < /强>?)p> 我自己的感觉是,由于JPA引擎足够复杂,而且肯定像所有软件一样,并非没有bug,因此最好是忍受非规范化的表,而不是忍受与复

我遇到过一些SO讨论和其他帖子(例如,和),其中将复合主键与JPA一起使用被描述为可能避免的事情,或者由于遗留数据库的需要,或者被描述为具有“毛茸茸的”角落案例。既然我们从头开始设计一个新的数据库,并且没有任何遗留的问题需要考虑,那么我们建议它还是更安全的,以避免具有<强> JPA < /强>的复合主键(<强> Hibernate < /强>或<强> Eclipse >> < /强>?)p>
我自己的感觉是,由于JPA引擎足够复杂,而且肯定像所有软件一样,并非没有bug,因此最好是忍受非规范化的表,而不是忍受与复合主键相关的bug带来的恐惧(基本原理是数字单列主键和外键是JPA引擎支持的最简单的用例,因此应该尽可能没有bug)。

我已经尝试了这两种方法,我个人更喜欢避免复合主键,原因如下:

  • 您可以创建一个包含id字段的超类,这样您就不必在所有实体中使用它
  • 实体创建变得更加容易
  • 总的来说,JPA的表现更好
  • 引用实体变得更容易。例如,在一个集合中存储一组id,或者在网页的查询字符串中指定一个id,只需使用一个数字就可以大大简化
  • 可以使用超级类中指定的一个equals方法(该方法适用于所有实体)
  • 如果您使用JSF,您可以创建一个通用转换器
  • 使用DB客户端时更容易指定对象
但它也带来了一些不好的方面:

  • 少量的非规范化
  • 在某些情况下,使用未持久化的对象(如果您使用自动生成的ID,您应该这样做)可能会带来麻烦,因为平等方法等需要一个ID才能正常工作