未找到 Json 类型 model.User 的 JsObject 序列化程序。尝试为此类型实现隐式 OWrites 或 OFormat
No Json serializer as JsObject found for type model.User. Try to implement an implicit OWrites or OFormat for this type
我正在使用带有 Scala 和 Reactive Mongo 的 Play 框架将对象保存到我的 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)
我正在导入 中提到的必要包。
我还导入了 json.JsonFormatters._,其中包括:
implicit val userWrites : Format[User] = Json.format[User]
但是,它仍然返回相同的错误,告诉我它无法从 JsObject 转换为 User。我看不到这里的 JsObject 在哪里,考虑到我的用户实体只是一个具有 5 个字段的案例 class。
case class User(var id: BSONObjectID, var name: String, var email: String, var companyName: String, var created: Date) {
}
有什么想法吗?我错过了什么?
您正在使用 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) 在应用程序中没有任何意义。因此,您不应使用它。如果您需要一个 Id,例如 运行 数字,对于用户,您可以定义一个新字段。这是一个例子:https://github.com/luongbalinh/play-mongo/blob/master/app/models/User.scala
我正在使用带有 Scala 和 Reactive Mongo 的 Play 框架将对象保存到我的 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)
我正在导入
implicit val userWrites : Format[User] = Json.format[User]
但是,它仍然返回相同的错误,告诉我它无法从 JsObject 转换为 User。我看不到这里的 JsObject 在哪里,考虑到我的用户实体只是一个具有 5 个字段的案例 class。
case class User(var id: BSONObjectID, var name: String, var email: String, var companyName: String, var created: Date) {
}
有什么想法吗?我错过了什么?
您正在使用 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) 在应用程序中没有任何意义。因此,您不应使用它。如果您需要一个 Id,例如 运行 数字,对于用户,您可以定义一个新字段。这是一个例子:https://github.com/luongbalinh/play-mongo/blob/master/app/models/User.scala