![](/img/trans.png)
[英]JPA / Hibernate unidirectional one-to-one mapping with shared primary key
[英]How to make sure hibernate 5 persists in the correct order in a one-to-one relationship with shared primary key
TLDR:將 Hibernate 版本從 3. 切換到 5 .. 現在,具有僅映射在一個類中的共享主鍵的 OneToOne 關系以錯誤的順序保留兩個實體,違反了外鍵約束。 如何更改順序?
在從 jboss 7 實例遷移到當前的 wildfly 的過程中,我的團隊還不得不將我們的 hibernate 版本從 3 更新到 5.3.10。
在這樣做時,我遇到了我們的一個實體構造的問題,其中我撞到了磚牆。
一般概念如下:
我有一個主實體類,它有多個“模塊”作為屬性,它們共享主實體類的主鍵。 這些模塊本身就是實體類,並持有各種邏輯和進一步的關系。 但是,模塊實體沒有任何其他持久屬性。 它們也沒有對主實體類的引用。
在這方面,它是(在 Java 的面向對象世界中)與共享主鍵的單向關系(我理解共享主鍵使其成為數據庫的雙向關系)。
Java 代碼將是這樣的:
@Entity(name = "mainEntity")
@Table(name = "main_entity")
public class MainEntity {
// Business Logic ...
@Id
private Long id;
@OneToOne( targetEntity = ModuleA.class, cascade = CascadeType.ALL, optional = false,
orphanRemoval = true )
@PrimaryKeyJoinColumn( name = "id", referencedColumnName = "id" )
private ModuleA moduleA;
// More Modules...
}
@Entity(name=moduleA)
@Table(name=module_a)
public class ModuleA {
@Id
private Long id;
// other relationships to entirely different entities,
// but no reference to mainEntity or other "modules"
}
在我們以前的系統中,這工作得很好。 當使用類似
entityManager.persist(mainEntity);
模塊將首先被持久化,然后是 mainEntity。
但是,在我們更新的休眠版本中,情況並非如此。 使用此映射,插入順序顛倒,entityManager 將首先嘗試持久化 mainEntity。 這會導致違反應防止表之間不一致的外鍵約束。
附注:我嘗試改變
@PrimaryKeyJoinColumn(...)
進入
@MapsId(value="id")
這實際上正確地改變了持久性順序。 但是,這樣做會導致 hibernate 不再正確理解共享主鍵 -> 雖然由於某種原因堅持工作,
entityManager.find(ModuleA.class,primaryKey);
不起作用,產生諸如“列 mainEntity.moduleA_id 不存在”之類的錯誤。
有沒有一種你能想到的方法來表達需要首先持久化模塊,就像 Hibernate 3 為我們所做的那樣?
我將不勝感激任何幫助。
PS:這是我的第一個問題,如果需要更多信息,或者配方有問題,請告訴。 :)
好的,經過一些分析后,我想分享我們對此所做的工作。
首先,問題中提供的映射適用於 Hibernate 3.6.10.Final,直到 Hibernate 5.2.13.Final 開始失敗。 奇怪的是,從 5.4.0.CR1 開始它又開始工作了。
我們還沒有找到在約束就位的情況下繼續使用此映射的方法。 在我們的例子中,我們認為約束不值得麻煩,但為了更可靠地映射這種事情,我們發現使用 @MapsId 更成功。 在那里,模塊需要對 MainEntity 的引用,並在其上使用 @MapsId 來派生其 id。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.