Scala:如何使用ReactiveMongo查询的Date字段映射嵌套的案例类?

时间:2019-02-11 09:40:59

标签: json scala mapping reactivemongo

我有两个案例类,用户1-> N关键字,我想在Scala中使用ReactiveMongo查询和更新。

这是课程:

case class Keyword(
  keyword:        String,
  var lastUpdate: Date,
  var counter:    Int)

object Keyword {
  implicit val keywordWriter: OWrites[Keyword] = (
    (JsPath \ "keyword").write[String] and
    (JsPath \ "lastUpdate").write[Date] and
    (JsPath \ "counter").write[Int])(unlift(Keyword.unapply))

  implicit val keywordReader: Reads[Keyword] = (
    (JsPath \ "keyword").read[String] and
    (JsPath \ "lastUpdate").read[Date] and
    (JsPath \ "counter").read[Int])(Keyword.apply _)
}

case class User(
  _id:          Option[BSONObjectID],
  name:         String,
  lastname:     String,
  twitterUser:  String,
  var keywords: Option[Seq[Keyword]] = None)

object User {

  implicit val userWriter: OWrites[User] = (
    (JsPath \ "_id").writeNullable[BSONObjectID] and
    (JsPath \ "name").write[String] and
    (JsPath \ "lastname").write[String] and
    (JsPath \ "twitterUser").write[String] and
    (JsPath \ "keywords").writeNullable[Seq[Keyword]])(unlift(User.unapply))

  implicit val userReader: Reads[User] = (
    (JsPath \ "_id").readNullable[BSONObjectID] and
    (JsPath \ "name").read[String] and
    (JsPath \ "lastname").read[String] and
    (JsPath \ "twitterUser").read[String] and
    (JsPath \ "keywords").readNullable[Seq[Keyword]])(User.apply _)

  // implicit val userFormatter = Json.format[User]
}

写的部分还可以,因为我看到了此类生成的MongoDB文档模型,即User集合中关键字字段中的嵌套文档列表。 问题出现在“读取”部分,当我运行此错误时:

play.api.libs.json.JsResultException: JsResultException(errors:List((/keywords(0)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(1)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(2)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(3)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray()))), (/keywords(4)/lastUpdate,List(JsonValidationError(List(error.expected.date),WrappedArray())))))
    at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:61)
    at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:33)
    at reactivemongo.core.protocol.ReplyDocumentIterator$.$anonfun$parse$1(protocol.scala:141)
    at scala.collection.Iterator$$anon$10.next(Iterator.scala:455)
    at scala.collection.Iterator$ConcatIterator.next(Iterator.scala:226)
    at reactivemongo.api.DefaultCursor$Impl.$anonfun$headOption$2(DefaultCursor.scala:332)
    at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:654)
    at scala.util.Success.$anonfun$map$1(Try.scala:251)
    at scala.util.Success.map(Try.scala:209)
    at scala.concurrent.Future.$anonfun$map$1(Future.scala:288)
    at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
    at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

我也试着放: 隐式val keywordFormatter = Json.format [Keyword] 隐式val userFormatter = Json.format [User]

但结果相同。

有人可以帮我吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

使用BSONDateTime代替日期

import play.api.libs.json._
import play.api.libs.functional.syntax._
import reactivemongo.bson.BSONDateTime
import reactivemongo.play.json.BSONFormats._

case class Keyword(
  keyword:        String,
  lastUpdate: BSONDateTime,
  counter:    Int)

object Keyword {

  implicit val keywordWriter =  new OWrites[Keyword]{
    override def writes(keyword: Keyword): JsObject = Json.obj(
      "keyword" -> keyword.keyword,
      "lastUpdate" -> keyword.lastUpdate,
      "counter" -> keyword.counter,
    )
  }

  implicit val keywordReader: Reads[Keyword] = (
    (JsPath \ "keyword").read[String] and
    (JsPath \ "lastUpdate").read[BSONDateTime] and
    (JsPath \ "counter").read[Int])(Keyword.apply _)
}