[英]How to save an object, using Hibernate as persistence, with a foreign key using Jackson?
如果您已經回答了這個問題,我想向您道歉。
請注意,該項目正在使用Spring Boot,Jackson和Hibernate。
無論如何,我分叉了Jasenko Hadziomeragic的一個項目。 我想知道他如何在Jasenko的項目Product對象中保存對象。 在此項目中,Product對象如下所示(請注意,我刪除了部分代碼以專注於外鍵):
@JoinColumn(name = "member_id")
@NotNull
private Long member_id;
我可以使用以下JSON保存新記錄:
{
"name" : "Product 2",
"member_id" : "1"
}
這行得通,但從我在互聯網上搜索到的內容來看,最好改用以下方法:
public class Product {
@ManyToOne()
@JoinColumn(name="member_id")
private Member member;
/* A getter/setter for the memeber id*/
public Long getMember_id() {
return this.member.getId();
}
public void setMember_id(Long member_id) {
this.member.setId(member_id);
}
}
我試圖用上面的json保存新記錄,但出現此錯誤:
java.lang.NullPointerException: null
at com.jersey.representations.Product.setMember_id(Product.java:100)
這是指向我的github的鏈接,其中包含修改后的代碼。
我還檢查了與我所關心的類似的SO問題 。 但是首先要執行的操作是先發送選擇查詢以填充Member對象。 但這意味着在保存記錄之前,我必須請求另一個select語句。 這有點開銷,不是嗎?
UPDATE我在構造函數中添加了以下代碼:
public Product() {
this.member = new Member();
}
我確實解決了問題,但這是解決我的擔憂的正確方法嗎?
更新2
我要避免的是發送此JSON:
[
{
"id": 1,
"name": "Derp",
"currency": "599",
"regularPrice": 1203,
"discountPrice": 59,
"member": {
"id": 1,
"firstName": "Paul",
"lastName": "Andrews",
"email": "myemail@email.com"
}
},
{
"id": 2,
"name": "Another product ",
"currency": "909",
"regularPrice": 1203,
"discountPrice": 59,
"member": {
"id": 1,
"firstName": "Paul",
"lastName": "Andrews",
"email": "myemail@email.com"
}
},
{
"id": 3,
"name": "Another product 1",
"currency": "909",
"regularPrice": 1203,
"discountPrice": 59,
"member": {
"id": 1,
"firstName": "Paul",
"lastName": "Andrews",
"email": "myemail@email.com"
}
}
]
如您所見,成員不斷重復,而我只能發送memberId。
請嘗試使用帶有Model
和Product
持久性的簡單控制台應用程序學習Hibernate。 你不需要@JoinColumn
的products
,但@OneToMany
用mappedBy
屬性。 您可以將User稱為Member
的類似物,並將UserFriend稱為Product
。 在每個Product
您都需要User
外鍵-以這種方式將產品添加到成員。 對於實驗,您可以使用this或this 。
好吧,我終於要使它工作了。 我不知道確切的位置,但是我可以肯定地說這不是由Jackson問題編組的JSON。
這是我的解決方案:
首先,我找不到解決方案,而是將其添加到具有外鍵的類中:
@Entity
public class Product {
public Product() {
this.member = new Member();
}
@ManyToOne()
@JoinColumn(name="blargh")
private Member member;
/** Jackson can't instantiate and object automatically so you have to help it **/
/** By creating the object right after Product is initialzed by some other code **/
public Long getMobileNum() {
return this.member.getMobileNum();
}
public void setMobileNum(Long mobileNum) {
this.member.setMobileNum(mobileNum);
}
}
下一步在另一個類中查找Id注釋。
@Entity
public class Member {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Id
private Long mobileNum;
}
我故意使注釋錯誤以證明觀點。 在Product類中,將其鏈接到Member類的外鍵是mobileNum。 如果mobileNum或任何外鍵都帶有@Id注釋,則Hibernate將正確綁定它,並且在保存對象時不會有任何問題。
但是,如果未使用@Id,Hibernate注釋外鍵(即使Jackson正確地將JSON映射到對象), 它將無法正確綁定它,從而導致null值 。 Google搜索關鍵字:對象引用了未保存的臨時實例
我認為添加Cascade並不是一個好的解決方案,因為它只會在Member類中創建更多記錄。 如果記錄已經存在,它將繼續創建EVEN! (嘗試對mobileNum施加唯一約束,並刪除@Id注釋。
總的來說,這周在休眠狀態真的讓我很疲憊。 如果您是具有優化現有SQL經驗的開發人員,並且只想將其轉換為代碼,請遠離Hibernate。 使用MyBatis,即使它有很多樣板,手動創建SQL也比使用Hibernate令人滿意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.