[英]Play Framework / Scala: abstract repository and Json de/serialization
This question is maybe more about Scala than Play, but here it is: I am trying to achieve an abstraction of a repository for common DB operations. 这个问题可能与Scala有关,而不仅仅是Play,但问题在于:我正在尝试为常见的DB操作实现存储库的抽象。
trait Entity {
def id: UUID
}
trait Repository[T <: Entity] {
val JSON_KEY_ID = "_id"
def collection: JSONCollection
def insert(t: T): Future[Either[String, T]] = {
collection.insert(t).map(wr => if (wr.ok) Right(t) else Left(wr.getMessage()))
.recover { case t => Left(t.getMessage) }
}
def update(t: T): Future[Either[String, T]] = {
val selector = Json.obj(JSON_KEY_ID -> t.id.toString)
collection.update(selector, t).map(wr => if (wr.ok) Right(t) else Left(wr.getMessage()))
.recover { case t => Left(t.getMessage) }
}
}
Then I have the objects I would like to use this with: 然后,我有想要与之配合使用的对象:
case class UserDAO(id: UUID) extends Entity[UserDAO]
object UserDAO {
val JSON_KEY_ID = "_id"
implicit val userDaoWrites: OWrites[UserDAO] = new OWrites[UserDAO] {
def writes(user: UserDAO): JsObject = Json.obj(
JSON_KEY_ID -> JsString(user.id.toString)
)
}
implicit val userDaoReads: Reads[UserDAO] = (
(__ \ JSON_KEY_ID).read[UUID]
)(UserDAO.apply _)
}
and then I define its repository like this: 然后像这样定义它的存储库:
class UserRepository @Inject()(val reactiveMongoApi: ReactiveMongoApi) extends Repository[UserDAO] {
val db = reactiveMongoApi.db
override def collection: JSONCollection = db.collection[JSONCollection]("users")
}
The error I get is 我得到的错误是
No Json serializer as JsObject found for type T. Try to implement an implicit OWrites or OFormat for this type.
collection.insert(t).map(wr => if (wr.ok) Right(t) else Left(wr.getMessage()))
^
I tried to provide implicit OWrites[T]
, or even implicit OWrites[_]
to no avail. 我试图提供
implicit OWrites[T]
,甚至提供implicit OWrites[T]
implicit OWrites[_]
无济于事。 Maybe what I am trying to achieve is impossible. 也许我想要实现的目标是不可能的。 If not, how could I solve this?
如果没有,我该如何解决? Thank you very much.
非常感谢你。
You should be able to just use a context bound. 您应该能够只使用上下文绑定。
trait Entity {
def id: UUID
}
class Repository[T <: Entity : Writes] {
...
}
That will ensure that if there exists an implicit Writes[T]
in scope, it will be available for your insert and update functions. 这将确保如果作用域中存在隐式的
Writes[T]
,它将可用于您的插入和更新功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.