[英]Classes Relationships with JPA
我有一組具有以下UML圖的Java類:
public class Invoice {
@Id
private long id;
...
}
public class InvoiceDetail {
@Id
private long id;
...
private String productName;
private int quantity;
private double price;
}
我的目的是使用JPA批注在它們之間建立不同的關系。 Invoice和InvoiceDetail之間存在組成關系,可以分別使用@Embedded和@Embeddable批注分別解決 Invoice和InvoiceDetail的組成關系。 但是,通過建立InvoiceDetail,Class3和Class4之間的關系會出現問題。 在這些關系中,InvoiceDetail必須注釋為@Entity。 但是,如果在與@Entity和@Embeddable同時注釋一個類時,則相應的服務器將在部署期間引發運行時錯誤。 根據本網站的信息,我編寫了以下可能的解決方案:
@Entity
public class Invoice {
@Id
private long id;
...
@ElementCollection
@CollectionTable(name="INVOICEDETAIL", joinColumns=@JoinColumn(name="INVOICE_ID"))
private List<InvoiceDetail> invoiceDetails;
...
}
為了解決我的問題,這是正確的嗎?
提前致謝。
盡管很難知道這些類的真正含義,但是我認為您有一個設計問題。 Class1和Class2之間的組合表明,任何Class2實例僅存在於相應Class1實例的生命周期內。 但是另一方面,您具有Class3實例和Class4實例,它們可以/必須與Class2實例具有關系。
我要說的是,從我的角度來看,Class1和Class2之間的關系應該是簡單的關聯,而不是組成。 遵循此路徑,Class2將成為JPA中的一個Entity,那么您應該已解決了問題。
我通常將@Embeddable用於實例自身不存在的類,並將@Entity用於其實例可以不存在其他實例的任何類。 例如,可以以任何一種方式實現地址,但不能在同一系統上實現。 如果我不想鏈接地址,則地址為@Embeddable,但如果我想確保同一地址沒有保存在多行中,則地址必須為@Entity。
[編輯:在第1類和第2類重命名為Invoice和InvoiceDetails之后添加]
在Invoice和InvoiceDetails之間有一個組合很有意義。 但是我仍然認為您應該避免InvoiceDetails具有雙重性格。 我可以想到兩種解決方案(兩種重構):
我檢查了JPA應用程序,未發現@Entity和@Embeddable屬於同一類。 老實說,我懷疑這是否有可能,因為@Embeddable的官方javadoc說:
指定一個類,其實例存儲為擁有實體的固有部分並共享該實體的標識 。
由於@Entity具有自己的身份,因此您將嘗試聲明具有兩個身份的同一對象-這是行不通的。
[/編輯]
[edit2:為解決方案建議2添加代碼]
該代碼應在某些假設下工作(請參見下文)。 這是針對1:n關系的雙向導航的實現。
@Entity
public class Invoice {
@Id
private long id;
@OneToMany(mappedBy="invoice", cascade = CascadeType.ALL)
private List<InvoiceDetail> details;
}
@Entity
public class InvoiceDetails {
@Id
private long id;
@ManyToOne
@JoinColumn(name="invoice_id")
private Invoice invoice;
}
假設:表的命名方式與實體相同,invoice_details表的外鍵列的名稱為“ invoice_id”,兩個表的主鍵列的名稱均為“ id”。 請注意,mappedBy值“發票”是指實體字段,而名稱值“ invoice_id”是指數據庫表。 刪除仍由您的Class3或Class4實例引用其InvoiceDetails的Invoice對象時要小心-您必須首先釋放這些引用。
有關JPA的信息,請參考以下資源:
[/編輯]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.