Play framework + SLICK (Scalaquery) tutorial

13,819

Solution 1

Edit Now that Play2.1 has entered its RC process, we can use Slick. That's because Play2.1 is using Scala2.10 (RC as well) under the sea and because Slick will be the default DB access lib in the Typesafe stack.

To recall, Slick is now able to access RDBMS, and will target soon MongoDB as well. It's using a slick (^^) internal DSL for querying backends. This DSL is managed by Macros, that's why Scala 2.10 is required.

However, note that the macro system is in experimental status (even when Scala2.10 will be released). I don't know yet the potential caveats of such status on the Slick lib in the near future.

To enjoy this RC, go there Play2.1RC1, and browse the doc... there are a lot of changes out there, like the Json API f.i.


Hmmmm. Not sure that slick will work out of the box with Play as easy.

Because PLay 2.0 is actually build upon Scala 2.9.x, where slick is requiring 2.10 (for Macro).

So, at first there is a mismatch between the deps you're declaring (slick_2.10.0-M4 is saying I'm using Scala 2.10.0-M4) and the scala version that'll be used.

BTW, according to this example site (for Slick) your SBT deps seems ok. But the problem might come that the driver will required other deps (AST probably) and leave SBT discover the right version using the current scala version you're using (this is done by declaring dependency without scala version in the "articfact name") => This case, the AST won't be found because it doesn't exists for pre-2.10.

What could be tried is to define another version of scala for the whole project...

My 2c

Solution 2

Using Play 2.1, with the latest Slick release (1.0.1-RC1), you'd use:

val appDependencies = Seq(
  "com.typesafe.slick" %% "slick" % "1.0.1-RC1",
  ...
}
Share:
13,819
Salil
Author by

Salil

Most of my experience is in Java, C/C++, Python, Ruby, and Common Lisp. Wannabe functional programming guru.

Updated on June 07, 2022

Comments

  • Salil
    Salil almost 2 years

    Does anybody know of a good tutorial or a sample project (github) of using Play framework with SLICK (ScalaQuery)? I am struggling to make them work together.

    I am getting this error:

    [info] play - Application started (Dev)
    [error] application - 
    
    ! @6b13oi41c - Internal server error, for request [GET /listBooks] ->
    
    play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoClassDefFoundError: Could not initialize class scala.slick.ast.opt.Relational$]]
        at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1-2.0.2.jar:2.0.2]
        at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1-2.0.2.jar:2.0.2]
        at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor-2.0.2.jar:2.0.2]
        at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1-2.0.2.jar:2.0.2]
        at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor-2.0.2.jar:2.0.2]
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor-2.0.2.jar:2.0.2]
    Caused by: java.lang.NoClassDefFoundError: Could not initialize class scala.slick.ast.opt.Relational$
        at scala.slick.driver.BasicProfile$class.processAST(BasicProfile.scala:18) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
        at scala.slick.driver.PostgresDriver$.processAST(PostgresDriver.scala:69) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
        at scala.slick.driver.BasicProfile$class.createQueryBuilder(BasicProfile.scala:22) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
        at scala.slick.driver.PostgresDriver$.createQueryBuilder(PostgresDriver.scala:69) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
        at scala.slick.driver.BasicProfile$class.buildSelectStatement(BasicProfile.scala:23) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
        at scala.slick.driver.PostgresDriver$.buildSelectStatement(PostgresDriver.scala:69) ~[slick_2.10.0-M4-0.10.0-M2.jar:0.10.0-M2]
    [error] application - 
    

    Here is my Book model:

    package models
    
    import play.api.db._
    import play.api.Play.current
    
    import scala.slick.driver.PostgresDriver.simple._
    import scala.slick.ql.{MappedTypeMapper}
    import scala.slick.session.{Session, Database}
    
    case class Book(name: String, filename: String)
    
    object Book extends Table[(Long, String, String)]("book") {
    
      lazy val database = Database.forDataSource(DB.getDataSource())
      def id = column[Long]("id", O PrimaryKey, O AutoInc)
      def name = column[String]("name", O NotNull)
      def filename = column[String]("filename", O NotNull)
      def * = id ~ name ~ filename
    
      def findAll() : Seq[Book] = database.withSession { implicit db:Session =>
        (for(t <- this) yield t.name ~ t.filename).list.map(attrs => Book(attrs._1, attrs._2))
      }
    
      def create(book: Book): Unit = database.withSession { implicit db:Session =>
        this.name ~ this.filename insert(book.name, book.filename)
      }
    
    }
    

    EDIT:
    This is my Build.scala

    import sbt._
    import Keys._
    import PlayProject._
    
    object ApplicationBuild extends Build {
    
        val appName         = "PlayWithScala"
        val appVersion      = "1.0-SNAPSHOT"
    
        val appDependencies = Seq(
          // Add your project dependencies here,
          "postgresql" % "postgresql" % "9.1-902.jdbc4",
          "com.typesafe" % "slick_2.10.0-M4" % "0.10.0-M2"
        )
    
        val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
          // Add your own project settings here      
        )
    
    }
    
  • pedrofurla
    pedrofurla almost 12 years
    "according to this example site" what site?
  • pedrofurla
    pedrofurla almost 12 years
    Cool, didn't know Slick had its own repo
  • Somatik
    Somatik over 11 years
    play 2.1 RC1 is using scala 2.10
  • Salil
    Salil almost 11 years
    Yup, when I posted this question, there was not much information available. Now, the slick's github repo has examples about the integration.