4
votes

I am trying to serialize / deserialize using JSON and the Play Framework 2.1.0 and Scala 2.10. I am using Anorm, and I have a pretty simple Object that I want to store in a database. The Order is very simple:

case class Order(id: Pk[Long] = NotAssigned, mfg: String, tp: String)

In my controller, I am trying to build a REST interface to be able to accept and send an Order instance (above) as JSON. In there, I have the following code:

  implicit object PkFormat extends Format[Pk[Long]] {
     def reads(json: JsValue):Pk[Long] = Id(json.as[Long])
     def writes(id: Pk[Long]):JsNumber = JsNumber(id.get)
  }

However, this is failing to compile when I run "play test" with the following:

overriding method reads in trait Reads of type (json: play.api.libs.json.JsValue)play.api.libs.json.JsResult[anorm.Pk[Long]]; [error] method reads has incompatible type [error] def reads(json: JsValue):Pk[Long] = Id(json.as[Long])

Does anyone know why this is happening?

I have a lot of experience with JAXB, but I am realtively new to Play and Scala, and I haven't been able to find any answers so far. This seems like a pretty simple use case, actually I was hoping there would be a simpler solution (like Annotations), but I wasn't able to find one (at least not yet)

Any help is greatly appreciated!

Thanks

1

1 Answers

5
votes

play.api.libs.json.Reads trait defines reads method as:

def reads(json : play.api.libs.json.JsValue) : play.api.libs.json.JsResult[A]

Therefore, the response of reads method is expected to be JsResult[A], not A; that is, JsResult[Pk[Long]] and not Pk[Long]. In a case of success, you'll want to return this:

implicit object PkFormat extends Format[Pk[Long]] {
    def reads(json: JsValue):JsResult[Pk[Long]] = JsSuccess(Id(json.as[Long]))
    def writes(id: Pk[Long]):JsNumber = JsNumber(id.get)
}