Slick DB Sessions in Play 2 Framework for Scala

Slick DB Sessions in Play 2 Framework for Scala

Last updated:
Slick DB Sessions in Play 2 Framework for Scala
Source

Implicit DB Session

If you try to call a method that needs a DB Session (which is pretty much any method that accesses the Database) but you haven't got any, you'll probably see an error message like the following:

could not find implicit value for parameter s: play.api.db.slick.Config.driver.simple.Session

This happens because one of the ways to declare parameters for a function is to define them as implicit parameters. This means that you don't need to explicitly pass a DB Session to every method that queries the database, but it needs to be in scope.

One simple way you can define an implicit session is as follows:

//bring the current application into scope
import play.api.Play.current

object Example{

    //bring a db session into scope (the one that's defined in conf/application.conf)
    implicit val session = play.api.db.slick.DB.createSession

   //methods that require an implicit Session parameter can now be called here
}

An example of a method that requires an implicit DBSession

import play.api.db.slick.Config.driver.simple._
import play.api.Play.current


//this code example will not work unless you have defined a slick Table  Users
//and a corresponding case class User
object User {

    //a slick type representing the 'users' table
    val users = TableQuery[Users]

    //a method that takes a Long and an implicit DB Session and returns an Option[User]
    def findById(id: Long)(implicit session: Session): Option[User] = 
        users.filter(_.id === id).list.headOption
}

Calling DB withSession yourself

If you'd rather call DB withSession yourself (thereby opening a new DB connection), you can also do so like this:

import play.api.db.slick.DB
import play.api.Play.current
import play.api.db.slick.Config.driver.simple._

object SomeHelper {

  def getSomeInfoFromTheDB(id: Long):Option[Long] = {
    DB withSession{ implicit s =>
      // do whatever needs doing here
    }
  }

Troubleshooting

java.lang.RuntimeException: There is no started application

You'll get this error if you try the approach above from the console rather than from running your app via sbt run or something like that.

To fix that, you need to start a StaticApplication on the console, like this:

scala> new play.core.StaticApplication(new java.io.File("."))
[info] play - database [default] connected at jdbc:h2:file:./data/db
[info] play - Application started (Prod)
res18: play.core.StaticApplication = play.core.StaticApplication@22a730f2
... some lines ignored

References:

Dialogue & Discussion