Orm JPA-多个表之间具有共享主键的一对一关系
考虑以下示例: 我有三张桌子:水果、橘子和苹果 id在水果表中生成,是这里的主键 id也是Orange和Apple的主键(共享主键) 例如,如果水果中的id是1,2,3,4,5,那么场景可能是1,2是橙色的,3,4是苹果,5是橙色的 所以橙色表的id为1,2,5,而苹果表的id为3,4Orm 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 ========
===================================
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(员工的主键)也是作为外键的地址主键。