How to get past SQLException: Attempting to obtain a connection from a pool that has already been shutdown

StackOverflow https://stackoverflow.com/questions/19283421

Frage

I've got a Play (v 2.2.0) app using Typesafe Slick (v 1.0.1), and I'm trying to write a test (specs2) that seeds a PostgreSQL database, then makes a call to various controller actions to validate the existence of the data. In my test, I have:

 "Countries" should {
      "initialize" in {
        running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
          AppDB.database.withSession {
            implicit session: Session =>

              AppDB.dal.create
              AppDB.dal.seedForTests

              AppDB.dal.Countries.findAll().size must be_>=(1)
          }
        }
      }

by itself, this works fine. But, when I add another test action, like:

  "respond to Index()" in {
    val result = controllers.Countries.index()(FakeRequest())

    status(result) must equalTo(OK)
  }

my test fails with the message:

SQLException: Attempting to obtain a connection from a pool that has already been shutdown.

The relevant parts of the stacktrace are:

[error]     SQLException: Attempting to obtain a connection from a pool that has already been shutdown. 
[error] Stack trace of location where pool was shutdown follows:
[error]  java.lang.Thread.getStackTrace(Thread.java:1503)
[error]  com.jolbox.bonecp.BoneCP.captureStackTrace(BoneCP.java:559)
[error]  com.jolbox.bonecp.BoneCP.shutdown(BoneCP.java:161)
[error]  com.jolbox.bonecp.BoneCPDataSource.close(BoneCPDataSource.java:143)
[error]  play.api.db.BoneCPApi.shutdownPool(DB.scala:414)
[error]  play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:264)
[error]  play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:262)
[error]  scala.collection.immutable.List.foreach(List.scala:318)
[error]  play.api.db.BoneCPPlugin.onStop(DB.scala:262)
...

I've tried moving both the FakeApplication(...) and AppDB.database.withSession blocks higher in the code, as well as wrapping the val result = controllers.Countries.index(...) code in an AppDB.database.withSession wrapper, but still have had no luck.

Thank you for any direction.

War es hilfreich?

Lösung

You can use AroundExample to initialise your DB and run your tests:

class CountriesSpec extends mutable.Specification with AroundExample {

  def around[R : AsResult](r: =>R) = 
    running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
      AppDB.database.withSession { implicit session: Session =>
        AppDB.dal.create
        AppDB.dal.seedForTests
        AppDB.dal.Countries.findAll().size must be_>=(1)
        // just AsResult(r) with the latest 2.2.3 specs2 
        AsResult.effectively(r)
      }
    }

  "Countries" should {
    "respond to Index()" in {
      val result = controllers.Countries.index()(FakeRequest())
      status(result) must equalTo(OK)
    }
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top