在休眠 ORM 中使用一个强制外键和一个可选外键中的列
Posted
技术标签:
【中文标题】在休眠 ORM 中使用一个强制外键和一个可选外键中的列【英文标题】:Using a column in one mandatory and one optional foreign key in hibernate ORM 【发布时间】:2021-10-21 09:05:45 【问题描述】:我想在一个实体内的一个可选和一个强制复合外键中使用一个字段。
我有三个不同的实体,Team
、Person
和 Shard
。人员属于一个团队 ManyToOne。两个实体都有一个ShardID
,它是Shard
的外键。
所有团队和人员的 ID 仅在每个分片中唯一,但它们也只会引用具有相同分片 ID 的其他实体。他们的 ShardID 是他们主键的一部分。
Shard
---
PK ID
UNIQUE Name
Team
---
PK, FK1 ShardID
PK ID
---
FK1 (ShardID -> Shard)
Person
---
PK, FK1, FK2 ShardID
PK ID
FK2 TeamID
---
FK1 (ShardID -> Shard)
FK2 (ShardID, TeamID -> Team)
此外,Person
-> Team
关系是可选的。 Person
可能不是 Team
的成员,这可能会随着时间而改变。
在尝试在 JPA 中为 Person
对象建模时,我遇到了一个问题。显然,当我将ShardID
建模为主键的一部分和作为外键列时,休眠给了我Repeated column in mapping for entity
错误。我可以使用insertable = false, updatable = false
来防止这种情况发生:
// This contains the shard_id column
@EmbeddedId
protected PersonId id;
@ManyToOne(optional = true)
@JoinColumns(
@JoinColumn(name = "shard_id", insertable = false, updatable = false),
@JoinColumn(name = "team_id", nullable = true)
)
但我不能这样做,因为休眠要求所有JoinColumns
对insertable
和updatable
具有相同的设置,并且我需要能够在以后向该人添加一个团队。 ShardID
将始终存在,但 TeamID
可能不存在。
如何在休眠 JPA ORM 中实现这一点?我浏览了 O/R 建模的休眠文档,但找不到方法。我一直在研究表继承,但这感觉很不自然,并不能解决“可选问题”。
这个例子不包含我的实际数据模型,只是一个简化的例子。
【问题讨论】:
【参考方案1】:你可以尝试像这样使用@JoinColumnOrFormula
:
@JoinColumnOrFormulas(
@JoinColumnOrFormula(formula = @JoinFormula(value = "shard_id", referencedColumnName = "shard_id")),
@JoinColumnOrFormula(column = @JoinColumn(name = "team_id", referencedColumnName = "id", nullable = true))
)
【讨论】:
这个解决方案是特定于 Hibernate 的,对吗?我找不到 Hibernate 的JoinFormula
的实现,它采用“名称”属性并且不需要 value
属性,所以我尝试使用 shard_id
作为 value
。我还必须在JoinColumn
上指定referencedColumnName = "id"
。这不会在数据库中创建外键关系,但如果结构已经存在,我可以使用该对象。
是的,这是 Hibernate 特有的,因为 JPA 不支持这一点。我纠正了错别字。以上是关于在休眠 ORM 中使用一个强制外键和一个可选外键中的列的主要内容,如果未能解决你的问题,请参考以下文章