I tried the answer mentioned below but with no luck.
Sorry but this is not a proper description of what you did and what error you got.
I didn't manage to make automated mappings work without NullPointerException
s but the approach with recursive types seems to work.
DataSource
depends on Query
and Query
depends on DataSource
, so it's not clear how you're going to instantiate these classes. Probably with null
s, so at least some of the fields should be optional. For example I modified this place: case class Query(child:Option[DataSource], ...)
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class DataSource(subQuery: Query,name:String)
object DataSource {
implicit lazy val reads: Reads[DataSource] = (
(__ \ "subQuery").lazyRead(Reads.of[Query](Query.reads)) and
(__ \ "name").read[String]
)(DataSource.apply _)
implicit lazy val writes: Writes[DataSource] = (
(__ \ "subQuery").lazyWrite(Writes.of[Query](Query.writes)) and
(__ \ "name").write[String]
)(unlift(DataSource.unapply))
}
case class JoinQuery(joinType:String,query:Query)
object JoinQuery {
implicit lazy val reads: Reads[JoinQuery] = (
(__ \ "joinType").read[String] and
(__ \ "query").lazyRead(Reads.of[Query](Query.reads))
)(JoinQuery.apply _)
implicit lazy val writes: Writes[JoinQuery] = (
(__ \ "joinType").write[String] and
(__ \ "query").lazyWrite(Writes.of[Query](Query.writes))
)(unlift(JoinQuery.unapply))
}
case class Query(child:Option[DataSource], joinQuery:Seq[JoinQuery])
object Query {
implicit lazy val reads: Reads[Query] = (
(__ \ "child").lazyRead(Reads.optionWithNull[DataSource](DataSource.reads)) and
(__ \ "joinQuery").lazyRead(Reads.seq[JoinQuery](JoinQuery.reads))
)(Query.apply _)
implicit lazy val writes: Writes[Query] = (
(__ \ "child").lazyWrite(Writes.optionWithNull[DataSource](DataSource.writes)) and
(__ \ "joinQuery").lazyWrite(Writes.seq[JoinQuery](JoinQuery.writes))
)(unlift(Query.unapply))
}
Json.parse(
"""{"subQuery":{"child":{"subQuery":{"child":null,"joinQuery":[]},"name":"b"},"joinQuery":[{"joinType":"c","query":{"child":null,"joinQuery":[]}}]},"name":"a"}"""
).as[DataSource])
// DataSource(Query(Some(DataSource(Query(None,List()),b)),List(JoinQuery(c,Query(None,List())))),a)
Json.stringify(Json.toJson(
DataSource(Query(Some(DataSource(Query(None, Seq()), "b")), Seq(JoinQuery("c", Query(None, Seq())))), "a")
))
// {"subQuery":{"child":{"subQuery":{"child":null,"joinQuery":[]},"name":"b"},"joinQuery":[{"joinType":"c","query":{"child":null,"joinQuery":[]}}]},"name":"a"}