mongodbscalaplayframeworkreactivemongoplay-reactivemongo

BSONObjectIDFormat in trait BSONFormats is deprecated


I am using Reactive Mongo version 0.11.11 and I want to implement a method in my DAO which counts all documents by _id.

Here is my DAO:

import com.google.inject.Inject
import models.auth.{Team, Player}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json._
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json._
import reactivemongo.bson._
import reactivemongo.play.json.collection.JSONCollection

import scala.concurrent.Future

trait TeamDao {
  def find(_id: BSONObjectID): Future[Option[Team]]

  def find(name: String): Future[Option[Team]]

  def save(team: Team): Future[Team]

  def link(player: Player, team: Team): Future[Team]

  def update(team: Team): Future[Team]

  def count(team: Option[Team] = None): Future[Int]

  def count(_id: BSONObjectID): Future[Int]

  def countAllPlayersWithTeam(team: Team): Future[Int]
}

class MongoTeamDao @Inject()(reactiveMongoApi: ReactiveMongoApi) extends TeamDao {

  val players = reactiveMongoApi.db.collection[JSONCollection]("players")
  val teams = reactiveMongoApi.db.collection[JSONCollection]("teams")

  def find(_id: BSONObjectID): Future[Option[Team]] = teams.find(BSONDocument("_id" -> _id)).one[Team]

  def find(name: String): Future[Option[Team]] = teams.find(Json.obj("name" -> name)).one[Team]

  def save(team: Team): Future[Team] = teams.insert(team).map(_ => team)

  def link(player: Player, team: Team) = for {
    _ <- players.update(Json.obj("_id" -> player.id), Json.obj("$push" -> BSONDocument("teams" -> team._id)))
    team <- find(team._id.get)
  } yield team.get


  def update(team: Team) = for {
    _ <- teams.update(BSONDocument("_id" -> team._id), BSONDocument("$set" -> BSONDocument("name" -> team.name)))
    team <- find(team._id.get)
  } yield team.get


  def count(team: Option[Team] = None): Future[Int] = {
    val tmpTeam: Team = team.getOrElse {
      return teams.count()
    }
    teams.count(Some(Json.obj("name" -> tmpTeam.name)))
  }

  def count(_id: BSONObjectID): Future[Int] = {
    teams.count(Some(Json.obj("_id" -> _id)))
  }

  def countAllPlayersWithTeam(team: Team): Future[Int] = {
    players.count(Some(Json.obj("teams" -> team._id)))
  }

}

The problem is that I get the following error:

value BSONObjectIDFormat in trait BSONFormats is deprecated: Use [[reactivemongo.play.json.BSONFormats.BSONObjectIDFormat]]
[error]     teams.count(Some(Json.obj("_id" -> _id)))

I tried to replace the count method with:

def count(_id: BSONObjectID): Future[Int] = {
 teams.count(Some(BSONDocument("_id" -> _id))) 
}

But then I get the following compile error:

[error]  found   : reactivemongo.bson.BSONDocument
[error]  required: MongoTeamDao.this.teams.pack.Document
[error]     (which expands to)  play.api.libs.json.JsObject
[error] Error occurred in an application involving default arguments.
[error]     teams.count(Some(BSONDocument("_id" -> _id)))

Solution

  • You are mixing JSONCollection and BSON values.

    It's recommanded that you either use the JSON serialization with JSONCollection, or you use the default BSON serialization with BSONCollection.

    The deprecation message is a warning indicating to use the separate JSON library, instead of the former types previously included in the Play plugin.

    A BSONCollection can be resolved from the Play plugin as follows.

    reactiveMongoApi.database.map(_.collection[BSONCollection]("players"))
    

    The functions MongoConnection.(db|apply) and/or ReactiveMongoApi.db are deprecated, and the equivalent .database must be used (which returns Future[DefaultDB] instead of DefaultDB).