2 回答

TA貢獻1943條經驗 獲得超7個贊
當我們說 Errors 是擁有方時,這意味著關系的外鍵位于 Errors 表中(您正在通過@JoinColumn
)。因此,關系的擁有方是另一個實體的引用列將出現的一方。您可以通過@OneToMany
在 Transactions 實體中指定來定義關系的反面。
現在是關于交易和錯誤更新的問題的第二部分。在我看來,您可以通過應用適當的級聯模式(持久、刪除等)來更新與事務關聯的列表,這意味著您可以在@OneToMany(cascade=CASCADETYPE.MERGE)
指定反向關系的同時在事務實體中指定。這樣,如果每當您更新一個事務行時,也可以更新相應的錯誤行。
但是,我認為以其他方式級聯不是一個好習慣,即如果您更新子實體,則父實體也應該更新,因為它可能會導致許多數據不一致

TA貢獻1796條經驗 獲得超10個贊
在非雙向關系中,您定義一個映射。當您對該映射進行更改時,很明顯會發生什么 - 外鍵將被更新。因為只有一個映射,所以不會有沖突(許多 JPA 提供程序如果檢測到您有多個可寫的字段映射,就會拋出錯誤)。
對于雙向關系,這種控制不太明顯。在您的 transaction-Error 雙向關系中,假設它是一個 OneToOne 雙向映射,并且 Transaction1 設置為指向 Error1,反之亦然。假設您的應用程序確定 Transaction1 應該指向 Error2,并更改引用。如果 Error1 對 Transaction1 的引用沒有更正以反映這種情況,那么 JPA 在確定將什么值放入外鍵時就會出現問題。這就是所有權發揮作用的地方。擁有方被認為是可寫的映射,對它的更改控制外鍵字段。在 OneToMany 中,擁有方通常是 ManyToOne 反向引用,因為它更自然,因為外鍵無論如何都在持有 ManyToOne 的表中。
級聯與所有權無關。它只是意味著操作(持久化、合并、刪除、刷新)適用于關系引用的實體。如果使用cascade.all 調用em.refresh(transaction),事務和所有引用的錯誤將從數據庫中刷新。任何具有 ALL 或 REFRESH 級聯設置的 Error 關系也將被刷新,依此類推。如果你把它放在后面的引用上,JPA 應該檢測到它已經刷新了引用的 Transaction 實例,但為什么要冒險呢。通常,級聯選項應僅放置在需要避免意外后果的映射上。如果您不確定是否需要它,請在確定之前將其關閉。
在您的示例中,您可能會在應用程序將傳遞的根實體上進行級聯合并。對該圖所做的任何更改都可以通過單個合并調用輕松獲取,而無需在每個單獨的葉子上調用合并。您的模型的構建和序列化方式會影響合并,因此通常級聯選項僅放在根-> 葉關系上,以避免出現根-> 葉-> root' where root != root' 的問題。如果雙方都有級聯合并,則 root' 的狀態可能會覆蓋您在 root 中的更改。
添加回答
舉報