How to prevent an infinite loop when serializing a 3 node link in Java to JSON?

In my Spring MVC application, I have three classes - content, category and document - all of them are interconnected and must be serialized in JSON, but at the same time cause an infinite loop. The relationship is:

Content -> List<Category> -> List<Document> -> List<Content> -> (etc.) 

where Category is a property of Content, etc. I am trying to serialize it so that the link ends in a List (so that content.categories.documents appear in the view), but without finding any way to go This. Annotating with Jackson @JsonManagedReference and @JsonBackReference will not work, because some of these fields are already annotated as such for other relationships. You do not know how to do this, except for the possibility of creating a model corresponding to the corresponding type.

EDIT: if this helps, the error I received was "org.springframework.http.converter.HttpMessageNotWritableException: Failed to write JSON: Infinite recursion (StackOverflowError)" followed by a link chain trace.

+4
source share
4 answers

Perhaps look at the @JsonIdentityInfo annotation, which can be used to handle circular dependencies ( this post mentions this)? It will not work for Collection (alas), but it works with POJOs contained in collections, arrays and maps.

+1
source

@JsonManagedReference and @JsonBackReference pretty limited in the types of loops that they can handle. In particular, they can only be used to refer to parent-child relationships that are fairly static. In fact, they can only be used to process hierarchies, which are a strict tree. But in a large number of projects, object relations are actually represented by a graph that the two above-mentioned annotations simply cannot process. Jackson's designers realized this, and in version 2.0 of the library they introduced a new mechanism for processing object identifiers .

With this new mechanism, you can annotate all three of your objects ( Content , Document and Category ) using the @JsonIdentityInfo annotation, and then Jackson can serialize (and deserialize) them properly.

Simple code example:

 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "someUniquePropertyOfYourClass") public class Context { // fields, constructors, getters/setters } 
+1
source

Have you tried using @JsonIgnore? It worked better in my case when I used Hibernate in Spring MVC.

0
source

Have you tried converters?

Serialize each class separately with converters for the other two classes. For example, when serializing content, write converters for the category and document. Converters can be identifiers for a category and a document. When it comes to deserialization, first get the objects and remember their relationships. Then rebuild their relationship using identifiers.

0
source

Source: https://habr.com/ru/post/1490798/


All Articles