Play 应用程序启动期间未插入数据(使用 Play 2.4 和 reactivemongo 11.11)

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

我们将 Play Framework 2.4 与 mongodb 2.6 一起使用。但是自从我们将 reactivemongo 从 0.11.10 迁移到 0.11.11-play24 后,出了点问题。

我们在应用程序启动期间将一些数据加载到 mongodb。一切看起来都很好,应用程序已启动,日志中没有出现错误,但是没有数据被插入数据库

这是 Global.scala 中应用程序启动的代码:

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

为了注入 reactivemongo,我们决定暂时不使用 @Inject(),所以我们使用 current.injector 代替(根据 Reactivemongo documentation)。 注意:我们完全删除了 ReactiveMongoPlugin 的所有痕迹,因为它在 play-reactivemongo 0.11.11-play24.

中被弃用了

在这里我们定义我们的模型并注入 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")
}

application.conf 中,ReactiveMongoModule 通过以下行启用: play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"

应用程序日志:

[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)

这是来自 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 db: DefaultDB = Await.result(reactiveMongoApi.database, Duration.Inf)

问题是现在,reactiveMongoApi.db是同步的,如果直接使用,连接还没有完成(生命周期)。

所以我建议您要么等待数据库(如上面的代码),要么将回调注册到缓冲区中,该缓冲区将在数据库初始化 neem 时执行

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