播放 ReactiveMongo JSON 序列化泛型

Play ReactiveMongo JSON Serialization Generics

我在使用 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]))
  }

}

这是我的具体 class,其中包括 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]
}

当您创建 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])