簡體   English   中英

如何使用Jackson作為外鍵使用Hibernate作為持久性保存對象?

[英]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。

我發布的類似問題的另一個鏈接

請嘗試使用帶有ModelProduct持久性的簡單控制台應用程序學習Hibernate。 你不需要@JoinColumnproducts ,但@OneToManymappedBy屬性。 您可以將User稱為Member的類似物,並將UserFriend稱為Product 在每個Product您都需要User外鍵-以這種方式將產品添加到成員。 對於實驗,您可以使用thisthis

好吧,我終於要使它工作了。 我不知道確切的位置,但是我可以肯定地說這不是由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.

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