Search code examples
scalaplayframeworkslick

Unable to provision my slick setup using traits, NullPointerException


I rewrote my slick database layer to use traits (I was using classes before), and I am getting this error now:

It looks like my DatabaseConfig is null possible?

Unexpected exception ProvisionException: Unable to provision, see the following errors:

Error injecting constructor, java.lang.NullPointerException at play.api.DefaultApplication.class(Application.scala:221) while locating play.api.DefaultApplication while locating play.api.Application Caused by: java.lang.NullPointerException at play.api.db.slick.HasDatabaseConfig$class.driver(DatabaseConfigProvider.scala:142)

Below is my controller that uses the dbService, along with the traits etc that I am using to wire up my slick code using play-slick (2.02)

@Singleton
class HomeController @Inject() (dbService: DbService) extends Controller {

}

Module:

bind(classOf[DbService]).to(classOf[DbServiceImpl])

My slick db layer is setup as follows:

trait DbService extends
  UserTable
  with AccountTable {

  this: HasDatabaseConfigProvider[JdbcProfile] =>
  import driver.api._

  // ..

  }

@Singleton
class DbServiceImpl @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)
  extends DbService with HasDatabaseConfigProvider[JdbcProfile] {

  import driver.api._



}


trait AccountTable {
  this: HasDatabaseConfigProvider[JdbcProfile] =>
  import driver.api._

  lazy val accounts = TableQuery[AccountsTable]

  def getAccountById(id: Int): Future[Option[Account]] =
    db.run(accounts.filter(_.id === id).result.headOption)

  class AccountsTable(tag: Tag) extends Table[Account](tag, "accounts") {
      def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
      def companyName = column[String]("company_name")
        def * = (id, companyName) <> (Account.tupled, Account.unapply _)
  }
}

What seems to be the problem with my slick setup? I can't figure it out so far.

Update

The full stack trace is here: https://pastebin.com/CXzUB0Kx


Solution

  • The crash comes from here: https://github.com/playframework/play-slick/blob/2.0.2/src/core/src/main/scala/play/api/db/slick/DatabaseConfigProvider.scala#L142, so you are right, your DatabaseConfig (dbConfig) is null.

    This could be an initialization order problem. As you can see in the code referenced above, driver (being a lazy val) is certainly meant to be accessed after instanciation.

    Did you post the full stacktrace? The full stacktrace leading to the NullPointerException would allow identifying where this access comes from.

    Without a more precise stacktrace, you should ensure that you do not access driver or members imported through import driver.api._ too early. The most likely cause would we some val that you should turn into lazy val.

    After stacktrace update

    It seems that one of you lazy field here ApiService.scala:80 gets initialized, probably from the constructor of WebsiteTable here Schema.scala:544, called from ApiService.scala:81. Please review these locations or post the relevant code here if possible.