Why can't Scala find implicit value for parameter scala.slick.session.Session?

Viewed 2529

I am running a Scala Play 2.2 application with Slick 1.0.1. I am trying to wrap all of my database calls into a future try, for example:

object DbTeachers extends Table[DbTeacher]("edu_teachers") {
...
  def insertTeacher(school: Int, userId: String)
                   (implicit ec: ExecutionContext, db: Database) = 
    future { Try { db.withSession => { implicit s: Session =>
      (DbTeachers.school ~ DbTeachers.teacher).insert(school, userId)
  }}}
}

I find that the pattern future { Try { db.withSession => { ACTUAL_CODE_GOES_HERE }}} creates clutter and I would like to abstract it out as follows:

sealed class DbAsync[T](block: => T) {
  import play.api.libs.concurrent.Execution.Implicits.defaultContext
  implicit lazy val db = Database.forDataSource(DB.getDataSource())
  def get: Future[Try[T]] = future { Try { db.withSession { implicit s: Session =>
    block 
  }}}
}

object DbAsync {
  def apply[T](block: => T): Future[Try[T]] = new DbAsync[T](block).get
}

And then I can write my insertTeacher function as:

def insertTeacher(school: Int, userId: String) = DbAsync {
  (DbTeachers.school ~ DbTeachers.teacher).insert(school, userId)
}

However, the scala compiler (2.10.2) complains about this: could not find implicit value for parameter session: scala.slick.session.Session

According to my understanding, the insert() method does have an implicit session variable in scope within the DbAsync block, and because it is a call-by-name parameter, it shouldn't actually be evaluated until it is called within the DbAsync, at which time there would be an implicit session object in scope.

So, my question is, how do I convince the Scala compiler that there actually is an implicit Session object in scope?

1 Answers
Related