Json 和 Java - 循环参考
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17393812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Json and Java - Circular Reference
提问by Faabass
I'm having and issue with the Circular reference.
我对循环引用有疑问。
I have Rest Webservices which returns objects to the front end, the issue is when I try to return objects that have several references so as the result I get an infinite response, which generate
我有将对象返回到前端的 Rest Webservices,问题是当我尝试返回具有多个引用的对象时,结果我得到无限响应,从而生成
java.lang.IllegalStateException:
Cannot call sendError() after the response has been committed
The objects are generated automatically by Hibernate Code Generation and I need to have the circular reference in the backend, I've just need to remove it before send the information to the frontend using Hymanson.
这些对象是由 Hibernate Code Generation 自动生成的,我需要在后端有循环引用,我只需要在使用 Hymanson 将信息发送到前端之前将其删除。
The controller method header is:
控制器方法头是:
@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody eventResponse list(@RequestBody String sessionID) {
I'm not doing anything explicite to convert to Json, I'm a newby with this and I think that Hymanson resolved this automatically.
我没有做任何明确的事情来转换为 Json,我是这个新手,我认为 Hymanson 自动解决了这个问题。
回答by Vivin Paliath
There are two ways you can go about this. If you must expose your entity to the outside world, I recommend adding @JsonIgnore
on the property that is causing the circular reference. This will tell Hymanson not to serialize that property.
有两种方法可以解决这个问题。如果您必须向外界公开您的实体,我建议添加@JsonIgnore
导致循环引用的属性。这将告诉 Hymanson 不要序列化该属性。
Another way is to use the bidirectional features provided by Hymanson. You can either use @JsonManagedReference
or @JsonBackReference
. @JsonManagedReference
is the "forward" part of the property and it will get serialized normally. @JsonBackReference
is the "back" part of the reference; it will not be serialized, but will be reconstructed when the "forward" type is deserialized.
另一种方法是使用 Hymanson 提供的双向功能。您可以使用@JsonManagedReference
或@JsonBackReference
。@JsonManagedReference
是属性的“转发”部分,它将正常序列化。@JsonBackReference
是引用的“后面”部分;它不会被序列化,但会在“转发”类型反序列化时重建。
You can check out the examples here.
您可以在此处查看示例。
This addresses your comment: I think what you might want to do in this case is use a DTO that is visible to the outside world. I like this approach because I don't want to expose my entities to the outside. This means that the Hymanson annotations would be on the DTO and not on the enity. You would need some sort of mapper or converter that converts the entity to the DTO. Now when you make changes to your entity, they won't get propagated to the DTO unless you modify your mapper/converter. I think this is ok, because when you make a change to your entity you can decide if you want that change to be exposed or not.
这解决了您的评论:我认为在这种情况下您可能想要做的是使用对外界可见的 DTO。我喜欢这种方法,因为我不想将我的实体暴露在外面。这意味着 Hymanson 注释将在 DTO 上而不是在实体上。您需要某种映射器或转换器来将实体转换为 DTO。现在,当您对实体进行更改时,除非您修改映射器/转换器,否则它们不会传播到 DTO。我认为这没问题,因为当您对实体进行更改时,您可以决定是否要公开该更改。
UPDATE
更新
There is a good blog post herethat goes into detail about the various ways you can handle bidirectional relationships in Hymanson. It describes solutions that use @JsonIgnore
, @JsonManagedReference
and @JsonBackReference
, @JsonIdentityInfo
, @JsonView
and a custom serializer as well. It's a pretty comprehensive writeup of the various techniques that you can use.
这是一个很好的博客文章在这里是进入你能处理Hyman逊双向关系的各种方式的细节。它描述的解决方案,使用@JsonIgnore
,@JsonManagedReference
和@JsonBackReference
,@JsonIdentityInfo
,@JsonView
和自定义序列为好。这是您可以使用的各种技术的非常全面的文章。
回答by pavan
回答by Csongi77
A @JsonbTransient solved my problem to handel circular references:
@JsonbTransient 解决了我处理循环引用的问题:
@JsonbTransient // javax.json.bind.annotation.JsonbTransient
@ManyToOne
@JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
public AContainedEntity getAContainedEntity() {
return aContainedEntity;
}