2014-03-13 126 views
0

幫助解決問題。 我有2實體類:JPA和JSON序列化問題

1.

@Entity 
@Table(name = "topic") 
public class Topic { 
@Id 
@Column(name = "topic_id") 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 
@Column(name = "system_id") 
private int systemId; 
@Column(name = "topic_name") 
private String name; 
@OneToMany(mappedBy = "topic", fetch = FetchType.EAGER, orphanRemoval = true) 
private List<Faq> faqList; 
// getters and setters 
@Override 
public String toString() { 
    return "Topic{" + 
      "id=" + id + 
      ", systemId=" + systemId + 
      ", name='" + name + '\'' + 
      ", faqList=" + faqList + 
      '}'; 
} 
} 

2.

@Entity 
@Table(name = "faq") 
public class Faq { 
@Id 
@Column(name = "faq_id") 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 
@Column(name = "question") 
private String question; 
@Column(name = "answer") 
private String answer; 
@ManyToOne 
@JoinColumn(name = "topic_id") 
@JsonIgnore 
private Topic topic; 
//getters and setters  
@Override 
public String toString() { 
    return "Faq{" + 
      "id=" + id + 
      ", question='" + question + '\'' + 
      ", answer='" + answer + '\'' + 
      ", topicId=" + topic.getId() + 
      '}'; 
} 

}

我在toString方法寫入被迫只允許進行控制檯topic.id,因爲出現「StackOverflow」錯誤。序列化到JSON(傑克遜轉換器)的情況類似,因此我使用了@JsonIgnore註釋。一切都很好。但有一個問題:當我的System.out從controller.js {topic: {id: "1"}, question: "test", answer: "test"} JSON對象發送到服務器

@RequestMapping(method = RequestMethod.POST, value = "/faqs") 
@ResponseBody 
public Message editFaq(@RequestBody Faq faq) { 
    System.out.println(faq); 

    Message message = new Message("ok"); 
    return message; 
} 

我NullPointerException異常。我認爲這是因爲@JsonIgnore,當我嘗試獲取faq.toString(topic.getId())時,我得到了異常。我怎麼解決這個問題?

我解決了這個,添加路徑變量的帖子:

@RequestMapping(method = RequestMethod.POST, value = "/faqs/{topicId}") 
... 
Topic topic = new Topic(); 
topic.setId(topicId); 
faq.setTopic(topic); 

但這是秒殺。

回答

0

StackOverflow錯誤是因爲主題和常見問題之間的循環依賴關係。最好避免這些。

我也會避免在數據庫和HTTP組件(如REST或SOAP端點)中使用相同的類。對數據庫類的更改將立即反映在客戶端和服務器之間的數據結構中 - 而在SOAP的情況下,由於接口將發生更改,可能會導致客戶端發生故障。相反,在您的REST或SOAP組件中寫入一個類似的探測類(FaqVersion1,TopicVersion1),該類反映數據庫的字段,但僅包含您希望公開的那些字段。接受此類作爲您的方法(editFaq)中的參數並將內容映射到您的數據庫類的一個實例(Faq)。這乾淨地將您的數據庫代碼與外部接口(Web)分開。

您的網絡接口類(FaqVersion1)表示Faq可能有一個域名爲topicId這是一個簡單的Stringint參考Topic它屬於一個結果。然後,您的申請可以負責接受FaqVersion1,發現topicId並在內部創建Faq指向真實Topic

聽起來很簡單不是嗎?實際上,只要將數據庫隱藏在主應用程序後面,並確保Web組件是獨立的。這種分離對於您的應用程序的健康向前發展非常有益。

+0

謝謝。這是一種解決方法。如果我有很多課程,那對於應用程序來說不是一個很大的負擔嗎? – AlexSmith

+0

不是。如果您關心IDE的響應能力,您還可以使用Maven模塊化應用程序,但在運行時肯定不會擔心。更多的關注點是,儘管數據庫中需要保密,但在數據庫中看到一個新的字段奇妙地出現在公共API中。 – jmkgreen

+0

你說得對。你使用轉換一個類到另一個簡單的工具?你可以建議什麼? – AlexSmith