Original post : http://stackoverflow.com/questions/37275861/no-data-inserted-during-start-of-play-application-using-play-2-4-and-reactivemo
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 coruscant, 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 'coruscant'! 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
def insertOrUpdate( _id: ID, o: T) = {
println("* Will insert...")
collection.update(Json.obj("_id" -> _id), o, upsert = true)
}
[info] application - creating objects in database...
* Will insert...
[info] application - ReactiveMongoApi starting...
[info] application - ReactiveMongoApi successfully configured with DB 'coruscant'! Servers:
[localhost:27017]
* Will insert...
* Will insert...
* Will insert...
* Will insert...
[info] play.api.Play - Application started (Dev)
override def onStart(app: Application) {
Logger.info("creating object in database...")
someProducts.foreach{ product =>
ProductDB.insertOrUpdate(product._id, product).map { res =>
println("* Res..." + res)
}
}
}
Have check the Future result there?
--
override def onStart(app: Application) {
Logger.info("creating object in database...")
someProducts.foreach{ product =>
ProductDB.insertOrUpdate(product._id, product) recover {
case e: Throwable => println("** Failure ! " + e)
}
}
}
** Failure ! reactivemongo.core.errors.ConnectionNotInitialized: MongoError['Connection is missing metadata (like protocol version, etc.) The connection pool is probably being initialized.']
** Failure ! reactivemongo.core.errors.ConnectionNotInitialized: MongoError['Connection is missing metadata (like protocol version, etc.) The connection pool is probably being initialized.']
** Failure ! reactivemongo.core.errors.ConnectionNotInitialized: MongoError['Connection is missing metadata (like protocol version, etc.) The connection pool is probably being initialized.']
Connection isn't established yet, how can I avoid this ? I mean, is there a way to be totally sure that the connection is really established in this entry point ?
map is not a combinator to used to check a Future. If it's not mapped, the Future is failed. You should check the failure.
I guess you are using connection.db (deprecated) instead of connection.database.
current.injector.instanceOf[ReactiveMongoApi].database
Since it's now a Future[DefaultDB] instead of DefaultDB, I need to ensure that my Future is resolved to access to my collections and so on. Any idea / best practice on how to to do that properly ? (ex: Await ?)Nope. Even the plugin offer both .db (deprecated) and .database functions. Please use the right one.
Well, I recommend you to update your docs, really.
You guys are doing a good job workin' on your plugin, but please, be more explicit in your official website/docs/whatever.
There are still examples using this ".db" and no word saying it's deprecated or not in this version.
Anyway, thanks for the help, hope it will bring some clarity for other people getting lost.