Не найден сериализатор Json как JsObject для типа модели. Пользователь. Попробуйте реализовать неявный OWrites или OFormat для этого типа

Я использую Play Framework со Scala и Reactive Mongo, чтобы сохранить объект в моей базе данных mongodb. После этого http://reactivemongo.org/releases/0.10/documentation/bson/usage.html я придумал следующий код:

import java.util.Date

import com.google.inject.Inject
import model.User
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
import reactivemongo.bson.{BSONDocument, BSONDocumentReader, BSONDocumentWriter, BSONObjectID}
import play.modules.reactivemongo.json._, ImplicitBSONHandlers._
import json.JsonFormatters._

class UserRepository @Inject() (val reactiveMongoApi : ReactiveMongoApi) {

  private def users = reactiveMongoApi.db.collection[JSONCollection]("users")

  def save(user: User) = {
    users.insert(user)
  }

  implicit object UserWriter extends BSONDocumentWriter[User] {
    def write(user: User) = {
      BSONDocument(
        "_id" -> Option(user.id).getOrElse(BSONObjectID.generate),
        "name" -> user.name,
        "email" -> user.email,
        "companyName" -> user.companyName,
        "created" -> Option(user.created).getOrElse(new Date)
      )
    }
  }

  implicit object UserReader extends BSONDocumentReader[User] {
    def read(doc: BSONDocument): User = {
      User(
        doc.getAs[BSONObjectID]("_id").get,
        doc.getAs[String]("name").get,
        doc.getAs[String]("email").get,
        doc.getAs[String]("companyName").get,
        doc.getAs[Date]("created").get
      )
    }
  }
}

Я создал своих неявных авторов для преобразования в BsonDocument, поэтому я ожидал, что он будет должным образом преобразован и сохранен в базе данных.

Однако, когда я компилирую, я получаю:

UserRepository.scala:18: No Json serializer as JsObject found for type model.User. Try to implement an implicit OWrites or OFormat for this type.
[error] Error occurred in an application involving default arguments.
[error]     users.insert(user)

Я импортирую необходимые пакеты, как указано в сериализаторе No Json, поскольку JsObject найден для типа play.api.libs.json.JsObject. Я также импортирую json.JsonFormatters._, который включает в себя:

implicit val userWrites : Format[User] = Json.format[User]

Тем не менее, он по-прежнему возвращает ту же ошибку, сообщая, что не может конвертировать из JsObject в User. Я не вижу, где находится JsObject, учитывая, что моя сущность User - это просто case-класс с 5 полями.

case class User(var id: BSONObjectID, var name: String, var email: String, var companyName: String, var created: Date) {
}

Есть идеи? Что мне не хватает?

1 ответ

Решение

Вы используете BSONObjectID, и у вас нет неявного OFormat для этого типа. Попробуй это:

implicit val format = Json.format[User]    
implicit val userFormats = new OFormat[User] {
override def reads(json: JsValue): JsResult[User] = format.reads(json)

override def writes(o: User): JsObject = format.writes(o).asInstanceOf[JsObject]
}

Обычно BSONObjectID (_id) не имеет никакого смысла в приложении. Поэтому не стоит его использовать. Если вам нужен идентификатор, например, как порядковый номер, для пользователей, вы можете определить новое поле. Это пример: https://github.com/luongbalinh/play-mongo/blob/master/app/models/User.scala

Другие вопросы по тегам