playframework-2.4reactivemongoplay-reactivemongo

No data inserted during start of Play application (using Play 2.4 and reactivemongo 11.11)


We're using Play Framework 2.4 with mongodb 2.6. But since we migrated reactivemongo from 0.11.10 to 0.11.11-play24, something is wrong.

We're loading some data into mongodb during the start of the application. Everything looks fine, the application started, no errors occurred in the logs but no data were inserted in database.

Here is the code for the start of the application in Global.scala :

override def onStart(app: Application) {
   Logger.info("creating object in database...")
   someProducts.foreach{ product =>
     ProductDB.insertOrUpdate(product._id, product)
   }
}

To inject reactivemongo, we decided to not use the @Inject() for the moment, so we're using current.injector instead (according to the Reactivemongo documentation). NB : we totally removed every trace of ReactiveMongoPlugin since it's deprecated in play-reactivemongo 0.11.11-play24.

Here we define our model and we inject ReactiveMongo :

abstract class MongoDB[T: Format, ID: Format] {
   def collection: JSONCollection

   def insertOrUpdate( _id: ID, o: T) = collection.update(Json.obj("_id" -> _id), o, upsert = true)
}

object ProductDB extends MongoDB[Product, String] {
  override def collection = current.injector.instanceOf[ReactiveMongoApi].db.collection("products")
}

In application.conf, ReactiveMongoModule is enabled with this line : play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"

Logs of the app :

[debug] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application
[info] application - starting application, build at: 2016-05-17T13:00:18+0200
[info] application - creating object in database...
[info] application - ReactiveMongoApi starting...
[info] application - ReactiveMongoApi successfully configured with DB 'application'! Servers:
[localhost:27017]
[info] play.api.Play - Application started (Dev)

And here is the logs from mongodb :

2016-05-17T13:00:27.774+0200 [initandlisten] connection accepted from 127.0.0.1:65478 #3 (1 connection now open)
2016-05-17T13:00:27.833+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.833+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.880+0200 [initandlisten] connection accepted from 127.0.0.1:65479 #4 (2 connections now open)
2016-05-17T13:00:27.880+0200 [initandlisten] connection accepted from 127.0.0.1:65480 #5 (3 connections now open)
2016-05-17T13:00:27.880+0200 [initandlisten] connection accepted from 127.0.0.1:65481 #6 (4 connections now open)
2016-05-17T13:00:27.880+0200 [initandlisten] connection accepted from 127.0.0.1:65482 #7 (5 connections now open)
2016-05-17T13:00:27.880+0200 [initandlisten] connection accepted from 127.0.0.1:65483 #8 (6 connections now open)
2016-05-17T13:00:27.881+0200 [initandlisten] connection accepted from 127.0.0.1:65484 #9 (7 connections now open)
2016-05-17T13:00:27.881+0200 [initandlisten] connection accepted from 127.0.0.1:65485 #10 (8 connections now open)
2016-05-17T13:00:27.881+0200 [initandlisten] connection accepted from 127.0.0.1:65486 #11 (9 connections now open)
2016-05-17T13:00:27.882+0200 [initandlisten] connection accepted from 127.0.0.1:65487 #12 (10 connections now open)
2016-05-17T13:00:27.888+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.888+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.888+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.889+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.889+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.889+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.889+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.889+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.889+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.889+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.890+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.890+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.890+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.890+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.891+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.891+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms
2016-05-17T13:00:27.891+0200 [conn3] run command admin.$cmd { ismaster: 1 }
2016-05-17T13:00:27.891+0200 [conn3] command admin.$cmd command: isMaster { ismaster: 1 } ntoreturn:1 keyUpdates:0 numYields:0  reslen:178 0ms

Solution

  • You need to plug in after the database has been loaded:

        def db: DefaultDB = Await.result(reactiveMongoApi.database, Duration.Inf)
    

    The thing is that now, reactiveMongoApi.db is synchronous and, if used directly, the connection is not done yet (lifecycle).

    So I suggest that either you wait for the database (like code above) or your just register callbacks into a Buffer which will be executed when the database has neem initialized

        reactiveMongoApi.database.onSuccess {
          case _ => callbacks.foreach(_())
        }