![](/img/trans.png)
[英]Hibernate - OneToMany UniDirectional Mapping - SQLGrammarException
[英]OneToMany unidirectional mapping in Hibernate. Issue setting foreign key in referenced entity
假設有兩個實體: Parent和Child ,其中@OneToMany
映射從Parent到Child 。
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日志中看到的那樣。 但令人驚訝的是,在更新查詢后,我看到一些child
, parent_id
為null
。 這讓我感到驚訝。
所以,我去手動處理那個東西,並刪除了級聯。 然后我保存了這樣的實體:
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.