2014-03-13 76 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