簡體   English   中英

Hibernate中的OneToMany單向映射。 在引用實體中設置外鍵設置

[英]OneToMany unidirectional mapping in Hibernate. Issue setting foreign key in referenced entity

假設有兩個實體: ParentChild ,其中@OneToMany映射從ParentChild

class Parent {
    @Column(name="id")
    private Long id;

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id", referencedColumnName = "id")
    private List<Child> children;
}

class Child {
    @Column(name="id")
    private Long id;

    @Column(name="parent_id")
    private Long parentId;
}

如您所見,在我的例子中, Child表將一個外鍵存儲到Parent的主鍵中。 但我不希望這在我的Child實體中作為雙向映射。

現在出現的問題是,我無法在Child實例中設置parent_id

我創建了這樣的實例:

Parent parent = new Parent();
parent.setChildren(Lists.newArrayList(new Child(), new Child()));
parentDomainService.save(parent);

假設父端有級聯。 此方法首先保存Parent,然后保存Child實例。 然后它在子實例上運行更新查詢以更新parent_id ,正如我從Hibernate show_sql日志中看到的那樣。 但令人驚訝的是,在更新查詢后,我看到一些childparent_idnull 這讓我感到驚訝。

所以,我去手動處理那個東西,並刪除了級聯。 然后我保存了這樣的實體:

Parent parent = new Parent();
parent.setChildren(Lists.newArrayList(new Child(), new Child()));
parent = parentDomainService.save(parent);

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

這一個反彈在我身上,但有以下異常:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.somepkg.Child

我已經在SO上看到了很多關於異常的問題,我知道有很多問題,但是幾乎所有這些問題都涉及雙向映射,或者使用JoinTable進行單向映射。 它們都不適合我的情況。

這有什么燈嗎? 我沒有選擇。

PS:我正在處理的實際場景需要節省大量數據。 例如:50000個父記錄和250000個子記錄。 這就是為什么我不想要雙向映射。 因為保存Child會在后端創建一個帶有連接表的查詢。

我最感興趣的是解決方案,其中我不必在Child表上觸發兩次查詢。 正如我當前的應用程序中發生的那樣,這妨礙了性能。

當您刪除級聯時,父級不會保留引用的子元素和

parent = parentDomainService.save(parent);

父引用“未保存的瞬態”子實例,因此拋出異常。 如果您先保存父項,然后添加子項:

Parent parent = new Parent();
parent = parentDomainService.save(parent);
parent.setChildren(Lists.newArrayList(new Child(), new Child()));

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

然后不會拋出異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM