jpa - 与他人共享 OneToMany 的最佳做法是什么?
问题描述
假设我有一张看起来像这样的桌子。
K VARCHAR PK
V VARCHAR
它只是一个存储键和值条目的表。
现在,我希望它通常用于其他实体。
实体 A 具有多个属性,而实体 B 可以具有多个属性。
@Entity
class Property {
String key;
String value;
}
Property
将实体共享给其他实体的最佳做法是什么?
@Entity
class Some {
@OneToMany
private List<...Property> properties;
}
@Entity
class SomeOther {
@OneToMany
private List<...Property> properties;
}
我打算使用继承。
@Entity
@Inheritance
class Property {
}
我知道我可以扩展它。
@Entity
@DiscriminatorValue("SomeOther")
class SomeProperty extends Property {
}
@Entity
@DiscriminatorValue("SomeOther")
class SomeOtherProperty extends Property {
}
现在我的桌子应该是什么样子?
我应该创建SOME_PROPERTY
表吗?
或者我应该添加SOME_ID
到PROPERTY
表中?
解决方案
就个人而言,我会尽量保持简单。
当前映射,即:
@Entity
class Some {
@OneToMany
private List<Property> properties;
}
创建一个连接表,将 和 中的行链接SOME
起来PROPERTY
。你会得到几乎相同的InheritanceType.JOINED
。
如果您稍微修改映射:
@Entity
class Some {
@OneToMany
@JoinColumn
private List<Property> properties;
}
你最终会得到一个PROPERTY
指向的外键SOME
(并且重用这个映射SomeOther
会导致另一个外键)。你会得到几乎相同的InheritanceType.SINGLE_TABLE
。
在这里使用继承只会使事情复杂化。我会选择上述选项之一,或者使用更简单的映射:
@Entity
public class Some {
@ElementCollection
@MapKeyColumn(name = "K")
@Column(name = "V")
@CollectionTable(name = "PROPERTY", joinColumns = @JoinColumn(name = "some_id"))
private Map<String, String> properties;
}
上面将属性表示为 a Map<String, String>
,实际上它们就是这样。唯一的缺点是,当您重用此映射时(仅更改连接列名称,例如some_other_id
),您的 JPA 提供者可能难以生成模式。当然,您可以决定将不同实体的属性分开,在这种情况下,您可以更改集合表名称(然后您将获得 的等价物Inheritance.TABLE_PER_CLASS
)。
顺便说一句,我认为K
作为主键没有意义,假设键将针对Some
. 如果您决定使用其中一种解决方案@OneToMany
,我建议您向实体 添加一个代理键(一个@Id @GeneratedValue Long id
字段) 。Property
推荐阅读
- android - 项目单击执行方法上的导航抽屉
- python - 我如何获得写入输入所需的时间
- mongodb - 哪个 NoSQL DB 可用于多字段搜索
- reactjs - 如何使用 Jest 和 Native 测试库正确测试 React Native Modals
- node.js - 403 禁止在 Node.js 中使用 sendgrid 发送电子邮件
- spring-webflux - TcpClient 仅在 Spring WebFlux 控制器中返回第一个结果
- python - 在 numpy 数组中查找等值索引
- html - CSS 不允许将 div 的元素拆分到新行
- pytorch - 如何为 torch.cat 初始化张量
- c# - 如何使用 web 服务从用户控件使 jquery 自动完成工作