Java Hibernate连接表两个都是外键的组合键

Java Hibernate连接表两个都是外键的组合键,java,hibernate,orm,Java,Hibernate,Orm,我有两个不同的表,它们都有复合嵌入键。两个组合键在组合中具有相同的idA\u id。 我想使用联接表将表M与表D以一对多的关系联接起来。 下面是一些从XML ORM映射转换而来的伪java代码。所以请原谅这里写的任何错误。最终代码中的映射起作用,因此这里的输入错误不应受到责备 @Entity() 公共级M{ @EmbeddedId() 私有嵌入MID id; @OneToMany(name=“d”、@JoinTable(name=“M-d”, 连接柱={ @JoinColumn(name=“M\

我有两个不同的表,它们都有复合嵌入键。两个组合键在组合中具有相同的id
A\u id
。 我想使用联接表将表
M
与表
D
以一对多的关系联接起来。 下面是一些从XML ORM映射转换而来的伪java代码。所以请原谅这里写的任何错误。最终代码中的映射起作用,因此这里的输入错误不应受到责备

@Entity()
公共级M{
@EmbeddedId()
私有嵌入MID id;
@OneToMany(name=“d”、@JoinTable(name=“M-d”,
连接柱={
@JoinColumn(name=“M\u ID”,referencedColumnName=“M\u ID”),
@JoinColumn(name=“A\u ID”,referencedColumnName=“A\u ID”,table=“M”)
},
反向连接柱={
@InverseJoinColumn(name=“D\u ID”,referencedColumnName=“D\u ID”),
@InverseJoinColumn(name=“A\u ID”,referencedColumnName=“A\u ID”,table=“D”,insertable=“false”,updateable=“false”)
}
))
专用数据集;
}
@embeddeble()
嵌入MID的公共类{
@Basic()私有字符串A_ID;
@Basic()私有字符串M_ID;
}
@embeddeble()
嵌入的公共类{
@Basic()私有字符串A_ID;
@Basic()私有字符串D_ID;
}
如您所见,嵌入式程序都使用
A\u ID
,因此我们尝试将联接表中的第二个A\u ID设置为只读。应用程序启动,映射似乎正常

问题是,每当我想在
M
实体中插入一个新的
D
对象时,hibernate就会抛出一个SQL错误
无效列索引
,因为尽管准备好的语句如下所示是正确的,但hibernate只提供前两个参数,而不是所有三个参数。(hibernate提供的值是
(有效的\u M\u ID,有效的\u A\u ID)
,而不是提供3个值)

插入M_D(“M_ID”、“A_ID”、“D_ID”)值(?,?)
如果我将第二个inverseJoinColumn重命名为一个新的列名并使其可插入/可更新,问题就解决了。但是这意味着
A_ID
A_ID
A_REPEAT_ID
列中重复了
A_ID
,这是我想要避免的

@InverseJoinColumn(name=“A\u REPEAT\u ID”,referencedColumnName=“A\u ID”,table=“D”)
是否有一种方法可以告诉Hibernate,在执行插入时,我的
EmbeddedDId
需要正确映射到
D\u ID
a\u ID
(只读)? 我希望我的解释足够清楚,但请随时要求澄清。 Hibernate版本为
5.2.17-FINAL

编辑

在这种情况下,唯一重要的其他实体非常简单。但按照要求,我会写在这里

@Entity()
D类公共服务{
@EmbeddedId()
私有嵌入id;
/*这里还有其他基本字段*/
}

我不认为
insertable=false,updateable=false
能满足您的需要。如果希望
D
上的目标列
A\u ID
为只读,则必须将该列映射到目标实体
D
中,并在其中指定该列为
insertable=false,updateable=false
,但不在此关联上。

我建议使用
IdClass
进行此操作,当使用外键时,嵌入ID是一件麻烦事。除此之外,为了更清楚地了解您正在尝试做什么,您是否可以共享您的所有实体?@akortex91我添加了流程所需的最后一个实体(由于其简单性,以前没有添加)。此外,我们没有使用IdClass,因为我们的基础设施不可能使用它。我们依赖于一个只允许一个ID的通用内核(注释是在超类中完成的)。解决方案是使用嵌入式,因此上面的代码很遗憾您误解了。只读字段在联接表中,而不是在D实体中。我希望我的联接表有3列而不是4列(其中2列是相同的,因为复合ID是如何创建的),我明白你的意思了。不幸的是,对于
@JoinTable
,这是不可能的。我认为在本例中,您必须将联接表映射为实体,并在该实体上嵌入一个三列id。在那里,您仍然可以映射两个
@manytomone
关联,并使用
@OneToMany(mappedBy=“…”)
映射反向,但是您正在寻找的这种
@manytomy
关联不能用JPA AFAIK建模。通过不使用Hibernate,它通常是可能的,并且很容易实现。这就是为什么我认为JPA/Hibernate也应该有这样的方法,因此我发布了这个问题最后我选择了4个专栏,因为它对时间很敏感。但是我仍然觉得有一种方法可以让它工作:)就像我写的那样,这是可能的,但是您必须将联接表映射为实体。谢谢您的想法。不幸的是,这不是一个选项,因为我们使用的是DDD范式,只有聚合根可以修改实体。其他所有内容都需要是元素集合或联接表。这很复杂:)我真的以为Hibernate会有这样一种机制,通过配置自己处理这个问题