Воспроизвести общие принципы сериализации ReactiveMongo JSON

У меня проблема с использованием Play 2.5.x и ReactiveMongo Play. Я пытаюсь создать универсальный репозиторий, и у меня возникают серьезные проблемы при сериализации и десериализации объектов в базу данных. Это всегда дает мне следующую ошибку: No Json deserializer found for type E. Try to implement an implicit Reads or Format for this type.

Вот мой общий код:

package repositories.mongo

import javax.inject.Inject

import core.Entity
import play.modules.reactivemongo.ReactiveMongoApi
import reactivemongo.api.QueryOpts
import repositories.Repository

import scala.collection.Seq
import scala.concurrent.{ExecutionContext, Future}
import reactivemongo.play.json._
import play.api.libs.json._
import reactivemongo.play.json.collection.JSONCollection

class MongoRepository[K, E <: Entity[K]] @Inject()(reactiveMongo: ReactiveMongoApi) extends Repository[K, E] {

  protected def collection(implicit ec: ExecutionContext) = reactiveMongo.database.map(_.collection[JSONCollection](this.getCollectionName))

  protected def getCollectionName: String = {
    "users"
  }

  def getAll(count: Int, skip: Int)(implicit ec: ExecutionContext): Future[Seq[E]] = {
    this.collection.flatMap(_.find(Json.obj())
      .options(QueryOpts(skipN = skip))
      .cursor[E]().collect[Seq[E]](count))
  }

  def getFilter(count: Int, skip: Int, f: E => Boolean)(implicit ec: ExecutionContext): Future[Seq[E]] = {

    this.collection.flatMap(_.find(f)
      .options(QueryOpts(skipN = skip))
      .cursor[E]().collect[Seq[E]](count))
  }

  def getById(id: K)(implicit ec: ExecutionContext): Future[Option[E]] = {
    this.collection.flatMap(_.find(Json.obj("_id" -> id.toString)).one[E])
  }

  def create(entity: E)(implicit ec: ExecutionContext): Future[Option[E]] = {
    this.collection.flatMap(_.insert(entity)).flatMap(_ => Future.successful(Option(entity)))
  }

  def updateById(id: K, entity: E)(implicit ec: ExecutionContext): Future[Option[E]] = {
    this.collection.flatMap(_.findAndUpdate(Json.obj("_id" -> id.toString), entity)
      .map(_.result[E]))
  }

  def deleteById(id: K)(implicit ec: ExecutionContext): Future[Option[E]] = {
    this.collection.flatMap(_.findAndRemove(Json.obj("_id" -> id.toString))
      .map(_.result[E]))
  }

}

Вот мой конкретный класс, который включает сериализатор формата json.

package core

import play.api.libs.json.Json

trait Entity[K] {
  val id: K
}

case class User(
                 id: String,
                 name: String,
                 email: String
               ) extends Entity[String] {

}

object User {
  implicit val jsonFormat = Json.format[User]
}

person Marco Talento    schedule 23.01.2017    source источник


Ответы (1)


Когда вы создаете свой MongoRepository, вам нужно сказать, что E нужен json Format. Вы можете сделать это следующим образом:

class MongoRepository[K, E <: Entity[K]: Format]

// this is the same as

class MongoRespository[K, E <: Entity[K]](implicit formatter: Format[E]) 
person vdebergue    schedule 23.01.2017
comment
Спасибо, понятно, что я должен передать формат неявным параметром! :) - person Marco Talento; 23.01.2017