我在将一个外键Map到复合主键时遇到问题。我已经尝试过很多解决方案,包括这个帖子@onetomany和composite primary keys?。
所以情况是:
我有两个实体,比方说,box&color,复合主键在子级(color)。
@Entity
@Table(name = "box")
data class Box(
@Id
var id: Int = 0,
...
@OneToMany(cascade = [CascadeType.ALL])
@JoinColumns(
JoinColumn(name = "box_id", referencedColumnName = "id"),
JoinColumn(name = "locale", referencedColumnName = "locale"))
val colors: List<Color> = emptyList(),
)
@Entity
@Table(name = "color")
data class Color(
@EmbeddedId
var colorId: ColorId? = null,
) : Serializable
@Embeddable
data class ColorId(
var id: Int = 0,
@Column(name = "locale", insertable = false, updatable = false)
var locale: Locale = Locale.Germany
) : Serializable
所以,在box实体中,我尝试在box和color实体之间创建一个one-omanyMap。为此,我应该使用颜色实体的复合主键吗?如果我尝试将列连接到复合主键(就像我在box实体中所做的那样),我会得到一个错误消息,即-找不到逻辑列“locale”。
我如何解决这个问题?
或者这个问题的最佳解决方案是什么?
3条答案
按热度按时间0x6upsns1#
OneToMany
Map将连接一个Box
与许多Colors
. 因此,每个Color
需要指向一个Box
,所以每个Color
具有引用的主键的外键Box
(第页,共页)Int
类型)。@作为拥有方的一个公司
在Map中,应该使用单个联接列,因为此联接列将放置在
color
表格:您可以在我的github repo中查看工作示例(kotlin和java)。
@一个单亲作为一个逆(Map)边
数据库透视图
@OneToMany
作为拥有方和@OneToMany
作为反面(带有一个免费的@ManyToOne
)生成相同的数据库架构-数据库上的外键color
table。这就是为什么@JoinColumn
注解在这两种情况下看起来都是一样的,不管您将它放在哪一侧—目标是在many
侧面。应用前景
“拥有方”的区别在于应用程序的Angular 。jpa/hibernate只从拥有方保存关系。
因此,如果您更改了拥有方,则必须在应用程序代码中设置这一方(属性)。在这种情况下,必须设置
Box
在Color
,否则,jpa/hibernate将不会创建关系(即使您添加了Colors
至Box
). 此外,它不会引起任何例外,只是不会建立这种关系。下一次,你会找回你的Box
从数据库中Color
列表将为空。您可以查看工作示例,并在我的github repo中查看所有权的差异。
其他可能的问题
因为你和一个
OneToMany
在这个模型中,考虑一些其他可能的问题可能对您很有用。区域设置不可插入和不可更新
你可能会遇到的另一个问题是储蓄
locale
在ColorId
就像你标记的那样non-insertable
以及non-updatable
. 如果这是故意的,那就好了(在这种情况下,所有颜色都必须预先插入到数据库中,否则它们将在没有区域设置的情况下插入)。请记住,在这种情况下,设置locale.german对数据库没有影响。它将被默默地忽略,如果数据库中没有这样的颜色,它将以null插入。
仅指定给一个框的颜色
如果对这种关系进行建模,则只为一个框指定一种颜色(如德语中的黑色)。听起来有点不自然。通常,我会假设黑色可以分配给许多盒子。所以,这将是一个
ManyToMany
关系。再说一次,如果这是故意的,那没关系!colorid作为主键
这也有点不自然
Locale
作为主键的一部分Color
--德语中的黑色和英语中的黑色是不同的颜色?颜色本身独立于区域设置。颜色的名称取决于区域设置,但更重要的是ui。再说一次,如果这是故意的,那没关系!毕竟,这是你的商业模式!jdg4fx2g2#
你有两个选择。或者定义一个联接表
@JoinTable(name = "color_box_assignment", joinColumns = ...)
或使用反向Map:kpbwa7wx3#
在为您提供解决方案之前,我想向您提供有关
@OneToMany
以及@JoinColumns
注解。一
@OneToMany
Map表示这样一个事实,即应用了该Map的实体对另一个实体有许多引用。i、 东阿
Box
有很多关于Color(s)
对你来说。现在要对此进行建模,我建议您反转Map并使用
@ManyToOne
在颜色实体上。因为外键应该是彩色的。不能将外键从一个框到另一种颜色,因为可能有多种颜色。
另外,请注意它不是
@JoinColumns
,它是单数@JoinColumn
. 如果Box
实体包含Composite Primary Key
.话说回来,你们可以一起忽略
@OneToMany
Map,因为如果你需要得到一个盒子的所有颜色,在我看来,你可以而且应该使用Query
应用程序编程接口。一
@OneToMany
在这种情况下,Map只是一种方便。但如果你坚持要@OneToMany
Map然后您可以使用以下命令。