问题
I'm getting a:
No Json deserializer found for type Option[reactivemongo.bson.BSONObjectID]. Try to implement an implicit Reads or Format for this type.
When trying to deserialise my review object.
Review:
case class Review(override var id: Option[BSONObjectID] = None,
override var createdAt: Option[DateTime] = None,
override var updatedAt: Option[DateTime] = None,
grade: Int,
text: String,
originIPAddress: Option[String],
status: ReviewStatus,
origin: ReviewOrigin,
rId: Option[Long],
userId: Option[Long]
) extends TemporalModel
object Review {
import mongo_models.enums.EnumFormat._
implicit val reviewStatusReads = enumReads(ReviewStatus)
implicit val reviewOriginReads = enumReads(ReviewOrigin)
implicit val reviewReads: Reads[Review] = (
(__ \ "id").read[Option[BSONObjectID]] and
(__ \ "createdAt").read[Option[DateTime]] and
(__ \ "updatedAt").read[Option[DateTime]] and
(__ \ "grade").read[Int] and
(__ \ "text").read[String] and
(__ \ "originIPAddress").read[Option[String]] and
(__ \ "status").read[ReviewStatus] and
(__ \ "origin").read[ReviewOrigin] and
(__ \ "rId").read[Option[Long]] and
(__ \ "userId").read[Option[Long]]
)(Review.apply _)
implicit val reviewWrites: Writes[Review] = (
(__ \ "id").write[Option[BSONObjectID]] and
(__ \ "createdAt").write[Option[DateTime]] and
(__ \ "updatedAt").write[Option[DateTime]] and
(__ \ "grade").write[Int] and
(__ \ "text").write[String] and
(__ \ "originIPAddress").write[Option[String]] and
(__ \ "status").write[ReviewStatus] and
(__ \ "origin").write[ReviewOrigin] and
(__ \ "rId").write[Option[Long]] and
(__ \ "userId").write[Option[Long]]
)(unlift(Review.unapply))
val form = Form(
mapping(
"id" -> optional(of[String] verifying pattern(
"""[a-fA-F0-9]{24}""".r,
"constraint.objectId",
"error.objectId")),
"creationDate" -> optional(of[Long]),
"updateDate" -> optional(of[Long]),
"grade" -> number,
"text" -> text(minLength = 30, maxLength = 5000),
"originIPAddress" -> optional(of[String]),
"status" -> text,
"origin" -> text,
"rId" -> optional(of[Long]),
"userId" -> optional(of[Long])
) {
(id, createdAt, updatedAt, grade, text, originIPAddress, status, origin, rId, userId) =>
Review(
id.map(new BSONObjectID(_)),
createdAt.map(new DateTime(_)),
updatedAt.map(new DateTime(_)),
grade,
text,
originIPAddress,
ReviewStatus.withName(status),
ReviewOrigin.withName(origin),
rId,
userId
)
} {
review => {
Some(
(review.id.map(_.stringify)),
review.createdAt.map(_.getMillis),
review.updatedAt.map(_.getMillis),
review.grade,
review.text,
review.originIPAddress,
review.status.toString,
review.origin.toString,
review.rId,
review.userId
)
}
}
)
}
回答1:
Strange! My Intellij IDEA 12 didn't recognise the import and when I optimised the imports
import play.modules.reactivemongo.json.BSONFormats._
was removed which created the error.
One could also create a custom Format object to translate the BSONObjectID to json.
implicit object BSONObjectIDFormat extends Format[BSONObjectID] {
def writes(objectId: BSONObjectID): JsValue = JsString(objectId.toString())
def reads(json: JsValue): JsResult[BSONObjectID] = json match {
case JsString(x) => {
val maybeOID: Try[BSONObjectID] = BSONObjectID.parse(x)
if(maybeOID.isSuccess) JsSuccess(maybeOID.get) else {
JsError("Expected BSONObjectID as JsString")
}
}
case _ => JsError("Expected BSONObjectID as JsString")
}
}
But the import is enough in this case.
回答2:
Use this as per documentation: import reactivemongo.play.json._
来源:https://stackoverflow.com/questions/16898294/no-json-deserializer-found-for-type-optionreactivemongo-bson-bsonobjectid