2015-06-08 5 views
5

Ho una classe definita ricorsiva:JSON formato implicita con la definizione della classe ricorsiva

case class SettingsRepository(id: Option[BSONObjectID], 
          name: Option[String], 
          children: Option[List[SettingsRepository]]) 

con un formato JSON implicita, come di seguito:

implicit val repositoryFormat = Json.format[SettingsRepository] 

Come posso fare per risolvere questo errore di compilazione? :

No implicit format for Option[List[models.practice.SettingsRepository]] available. 
In /path/to/the/file.scala:95 

95 implicit val repositoryFormat = Json.format[SettingsRepository] 

ho cercato di definire una legge/scrittura/formato involucro pigro senza alcun successo ... Qualcuno sa un modo pulito per farlo?

Qualsiasi aiuto sarà apprezzato;

Grazie in anticipo.

risposta

6

Come hai scoperto, non è possibile utilizzare la nascita macro JSON qui, ma è possibile scrivere il proprio Format (nota che ho sostituito con BSONObjectIDLong per il bene di un esempio funzionante completo):

import play.api.libs.functional.syntax._ 
import play.api.libs.json._ 

case class SettingsRepository(
    id: Option[Long], 
    name: Option[String], 
    children: Option[List[SettingsRepository]] 
) 

implicit val repositoryFormat: Format[SettingsRepository] = (
    (__ \ 'id).formatNullable[Long] and 
    (__ \ 'name).formatNullable[String] and 
    (__ \ 'children).lazyFormatNullable(implicitly[Format[List[SettingsRepository]]]) 
)(SettingsRepository.apply, unlift(SettingsRepository.unapply)) 

Il trucco è fornire un'annotazione di tipo esplicito e utilizzare implicitly anziché un parametro di tipo su lazyFormatNullable.

+0

Grazie mille! Funziona perfettamente! – Xan

0

Per gli altri che sono venuti qui in cerca di una leggera variante in cui ridefiniamo reads e writes nella classe Format (come il example given sulla la documentazione API), è possibile dichiarare un riferimento pigro per l'oggetto necessario:

lazy val tweetFormat: Format[Tweet] = TweetFormat 
    implicit object UserFormat extends Format[User] { 
    //... 
    } 

    //... 
    implicit object TweetFormat extends Format[Tweet] { 
    //...