Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

Json and Java - Circular Reference

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

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 Jackson.

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 jackson resolved this automatically.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 Jackson not to serialize that property.

Another way is to use the bidirectional features provided by Jackson. 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.

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 Jackson 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.

UPDATE

There is a good blog post here that goes into detail about the various ways you can handle bidirectional relationships in Jackson. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...