Orm JPA-多个表之间具有共享主键的一对一关系

Orm JPA-多个表之间具有共享主键的一对一关系,orm,annotations,persistence,jpa-2.0,shared-primary-key,Orm,Annotations,Persistence,Jpa 2.0,Shared Primary Key,考虑以下示例: 我有三张桌子:水果、橘子和苹果 id在水果表中生成,是这里的主键 id也是Orange和Apple的主键(共享主键) 例如,如果水果中的id是1,2,3,4,5,那么场景可能是1,2是橙色的,3,4是苹果,5是橙色的 所以橙色表的id为1,2,5,而苹果表的id为3,4 =================================== Fruit =================================== id | shape ========

考虑以下示例:

我有三张桌子:水果、橘子和苹果

id在水果表中生成,是这里的主键

id也是Orange和Apple的主键(共享主键)

例如,如果水果中的id是1,2,3,4,5,那么场景可能是1,2是橙色的,3,4是苹果,5是橙色的

所以橙色表的id为1,2,5,而苹果表的id为3,4

=================================== 
 Fruit
===================================
 id     |   shape
===================================
  1     |   round
  2     |   round
  3     |   oblong
  4     |   oblong
  5     |   round
===================================


===================================
 Orange
===================================
 id     |   color    | taste
===================================
  1     |   orange   |  sour
  2     |   orange   |  sour
  5     |   orange   |  sour
===================================


===================================
 Apple
===================================
 id     |   density    | weight
===================================
  1     |   hard       |  200
  2     |   hard       |  220
  5     |   hard       |  230
===================================
问题:如何创建仅使用JPA注释捕获relationshipd的实体类(我不想使用hibernate generatedValue注释)。

如果纯JPA可以进行这样的注释,那么请指导我


通过强制两个Java字段(id和association)映射到同一列上来测试Nik

比如说,

class Orange {

   @Id
   @Column(name="id")
   long id;


   @OneToOne
   @JoinColumn(name="id")
   Fruit fruit;

   public Orange(Fruit fruit) {
      this.fruit = fruit;
      this.id = fruit.id;
   }

   protected Orange() { } // default constructor required by JPA
}

但我不知道JPA提供商会如何运作。

您的案例看起来像是一个被称为“泛化-专业化”的设计模式的实例,简称Gen-Spec。如何使用数据库表对genspec建模的问题在SO中一直存在

如果您在一个OOPL(如Java)中建模gen spec,您将使用子类继承工具为您处理细节。您只需要定义一个类来处理广义对象,然后定义一个子类集合,每个子类针对每种类型的专用对象。每个子类都将扩展广义类。这很简单,也很直接

不幸的是,关系数据模型没有内置子类继承,据我所知,SQL数据库系统也没有提供任何此类功能。但你并不是运气不好。您可以以一种与OOP的类结构并行的方式,将表设计为gen spec模型。然后,当向通用类添加新项时,您必须安排实现自己的继承机制。详情如下

类结构相当简单,gen类有一个表,每个spec子类有一个表。这是一个很好的例子,来自Martin Fowler的网站。注意,在这个图中,Cricketer既是一个子类又是一个超类。您必须选择哪些属性放在哪些表中。该图显示了每个表中的一个示例属性

棘手的细节是如何为这些表定义主键。gen类表以通常的方式获取主键(除非此表是另一个泛化的特化,如Cricketers)。大多数设计人员给主键一个标准名称,如“Id”。他们使用自动编号功能填充Id字段。spec类表获得一个主键,可以命名为“Id”,但不使用自动编号功能。相反,每个子类表的主键被约束为引用通用表的主键。这使每个专用主键都成为外键和主键。请注意,对于板球运动员,Id字段将引用球员中的Id字段,但Bowlers中的Id字段将引用板球运动员中的Id字段

现在,当您添加新项目时,您必须保持引用完整性,以下是如何操作。
首先在gen表中插入新行,为其所有属性(主键除外)提供数据。自动编号机制生成唯一的主键。接下来,将新行插入相应的等级库表,包括其所有属性的数据,包括主键。您使用的主键是刚刚生成的全新主键的副本。主键的这种传播可以称为“穷人的继承”

现在,当您需要所有的通用数据以及来自一个子类的所有专用数据时,您所要做的就是通过公共键连接两个表。所有不属于相关子类的数据都将从联接中删除。它光滑、简单、快速

实现genspec模式的SQL表的设计可能有点棘手。数据库设计教程通常会忽略这个主题。但它在实践中一再出现

如果你在网上搜索“泛化-专业化-关系建模”,你会发现一些有用的文章教你如何做到这一点。你也会在这个论坛上多次提到这个话题

这些文章通常向您展示如何设计一个表来捕获所有通用数据,以及如何为每个子类设计一个专门的表,该子类将包含特定于该子类的所有数据。有趣的部分涉及子类表的主键。您不会使用DBMS的自动编号功能来填充子类主键。相反,您将对应用程序进行编程,以将为通用表获得的主键值传播到相应的子类表


这将在通用数据和专用数据之间创建双向关联。每个专用子类的简单视图将收集通用和专用数据。一旦你掌握了窍门,它就很容易了,而且性能相当好。

看起来你想做的是继承(橙色延伸水果,苹果->水果)。你已经评估过这个选项了吗?这只是一个假设的例子。不,没有继承关系。它更像是员工地址关系。其中每个员工将有一个地址,每个地址将仅映射到一个员工。雇员和地址的主键都是共享的。表示员工Id(员工的主键)也是作为外键的地址主键。