{title:'Non-Tree Models and Recursion Detection', updated:'9.0.0'}

The Juneau Serializer API is designed to be used against POJO tree structures. It expects that there not be loops in the POJO model (e.g. children with references to parents, etc...). If you try to serialize models with loops, you will usually cause a StackOverflowError to be thrown (if {@link oaj.BeanTraverseContext.Builder#maxDepth(int)} is not reached first).

If you still want to use the Juneau serializers on such models, Juneau provides the {@link oaj.BeanTraverseContext.Builder#detectRecursions()} setting. It tells the serializer to look for instances of an object in the current branch of the tree and skip serialization when a duplicate is encountered.

For example, let's make a POJO model out of the following classes:

| public class A { | public B b; | } | | public class B { | public C c; | } | | public class C { | public A a; | }

Now we create a model with a loop and serialize the results.

| // Clone an existing serializer and set property for detecting recursions. | WriterSerializer serializer = Json5Serializer | .DEFAULT_READABLE | .copy() | .detectRecursions() | .build(); | | // Create a recursive loop. | A a = new A(); | a.b = new B(); | a.b.c = new C(); | a.b.c.a = a; | | // Serialize to JSON. | String json = serializer.serialize(a);

What we end up with is the following, which does not serialize the contents of the c field:

| { | b: { | c: { | } | } | }

Without recursion detection enabled, this would cause a stack-overflow error.

Recursion detection introduces a performance penalty of around 20%. For this reason the setting is disabled by default.