2017-01-23 16 views
0

Play 2.5.xとReactiveMongo Playを使用する際に問題があります。私はGeneric Repositoryを作成しようとしています。オブジェクトをデータベースにシリアライズして逆シリアル化するときに重大な問題があります。それは常に私に次のエラーを与える:No Json deserializer found for type E. Try to implement an implicit Reads or Format for this type.ReactiveMongo JSONシリアル化ジェネリック

ここに私の一般的なコードは次のとおりです。

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] 
} 

答えて

2

あなたの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]) 
+0

ありがとう、私は暗黙的なパラメータでフォーマットを渡す必要があることが理にかなっています! :) –