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(_())
}
我们将 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(_())
}