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
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.