Infinite Recursion when Serializing with Jackson

Hi there,

I have a tricky problem about “akka-serialization-jackson” (or maybe just that I am too newbie for akka jackson serialization :sweat_smile:)

I have a tree node case class LogNode which is used for a tree-like node type:

case class LogNode(var text: String,
                   dadNode: Option[AnyRef] = None,
                   var data: Option[(List[List[PyContextMetaType]],List[String],List[List[PyContextMetaType]])] = None,
                   children: ListBuffer[LogNode] = new ListBuffer[LogNode],
                   detailText: String = "") 

Like normal tree node definition, LogNode has children pointer named as “children”. But for algorithm reason, I also defined a pointer to the daddy node named as “dadNode” which points to the father node (of course that for the root node the dadNode will be None).

At first, I used SprayJson to handle marshaling of LogNode. And here comes an apparent infinite recursion problem because when doing marshaling of child node C1, sprayJson will look into dadNode C0, and then try to do nested marshalling of C0. When marshaling C0, it will find C1 again since C1 is one of the “children” of C0. But the lucky thing is that actually I do not need nested marshaling of dadNode. I only need dadNode to be marshaled as simple text as “dadNode” or “None” (actually I can even drop dadNode since it is only for algorithm purpose).

Since SprayJson uses toString() method to do the marshaling, so I override LogNode’s toString() method as below so that SprayJson will not do nested recursion when marshaling dadNode field:

case class LogNode(var text: String,
                   dadNode: Option[AnyRef] = None,
                   var data: Option[(List[List[PyContextMetaType]],List[String],List[List[PyContextMetaType]])] = None,
                   children: ListBuffer[LogNode] = new ListBuffer[LogNode],
                   detailText: String = "") 
{
  override def toString: String = {
    s"LogNode ($text,${
      dadNode match {
        case Some(r) => "dadNode"
        case None => "None"
      }
    },${children.toString})"
  }

}

Now it comes the problem. I need to send a List[LogNode] as content of “TaskDone” message:

object PayrollComputer {
  sealed trait Command  extends CborSerializable
  final case class TaskDone(eeChunk: List[LogNode]) extends Command
  ....
}

But when “replyTo ! TaskDone(listOfNode)” akka-serialization-jackson failed due to above mentioned Infinite Recursion error.

Now my question is how can I override the standard serialization method to avoid drill down serialization of dadNode?

Or do I have to implement my own serializer for LogNode?

Perhaps using the parent/child annotations or object identity annotation from Jackson would help serializing a tree with cycles like that? https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations#object-references-identity

1 Like

Hi there Johanandren,

Thanks so much.

< @JsonBackReference & @JsonManagedReference > solves the issue perfectly.

:+1: