Json和Java-循环引用

Json和Java-循环引用,java,json,jackson,circular-reference,Java,Json,Jackson,Circular Reference,我对循环引用有异议 我有RESTWebServices,它将对象返回到前端,问题是当我尝试返回具有多个引用的对象时,结果得到了一个无限的响应,这将生成 java.lang.IllegalStateException: Cannot call sendError() after the response has been committed 对象是由Hibernate代码生成自动生成的,我需要在后端有循环引用,我只需要在使用Jackson将信息发送到前端之前删除它 控制器方法标头为:

我对循环引用有异议

我有RESTWebServices,它将对象返回到前端,问题是当我尝试返回具有多个引用的对象时,结果得到了一个无限的响应,这将生成

java.lang.IllegalStateException: 
    Cannot call sendError() after the response has been committed
对象是由Hibernate代码生成自动生成的,我需要在后端有循环引用,我只需要在使用Jackson将信息发送到前端之前删除它

控制器方法标头为:

@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody eventResponse list(@RequestBody String sessionID) {

我没有做任何明确的事情来转换为Json,我是一个新手,我认为jackson会自动解决这个问题。

有两种方法可以解决这个问题。如果必须将实体公开给外部世界,我建议添加导致循环引用的属性。这将告诉Jackson不要序列化该属性

另一种方法是使用Jackson提供的双向功能。您可以使用或
@JsonManagedReference
是属性的“转发”部分,它将正常序列化
@JsonBackReference
是引用的“back”部分;它不会被序列化,但将在反序列化“forward”类型时重建

您可以查看示例

这就解决了您的意见:我认为在这种情况下,您可能希望使用外部世界可见的DTO。我喜欢这种方法,因为我不想把我的实体暴露在外面。这意味着Jackson注释将位于DTO上,而不是enity上。您需要某种映射器或转换器将实体转换为DTO。现在,当您对实体进行更改时,它们不会传播到DTO,除非您修改映射器/转换器。我认为这没关系,因为当您对实体进行更改时,您可以决定是否要公开该更改

更新


有一篇很好的博客文章详细介绍了在Jackson中处理双向关系的各种方法。它描述了使用
@JsonIgnore
@JsonManagedReference
@JsonBackReference
@JsonIdentityInfo
@JsonView
以及自定义序列化程序的解决方案。这是一篇相当全面的文章,涵盖了您可以使用的各种技术。

一个注释
@JsonIdentityInfo
就解决了这个问题。它还处理循环引用。

A@JsonbTransient解决了我对handel循环引用的问题:

@JsonbTransient // javax.json.bind.annotation.JsonbTransient
@ManyToOne
@JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
public AContainedEntity getAContainedEntity() {
       return aContainedEntity;
}

是的,我读过。但问题是我不想“触摸”Hibernate生成的实体。因为数据库一直在增长,所以任何时候我都会添加任何内容,我需要再次修改所有实体。据我所知,我必须修改这两个选项的实体,对吗?如果我使用@JsonManagedReference和@JsonBackReference可以吗?唯一的问题是当您的标识字段为空时。然后你回到了正方形1-循环引用。这个答案并不表示这个注释是在父类中还是在子类中。指出这些信息可以大大改进答案。