user2455862
user2455862

Reputation: 676

Play Slick 3.0 errors when creating class definition class

I spend about 2 hours or more trying to make this work. I've tried different imports(you can see in comments) and different version of slick but it still doesn't work. Here is my build.sbt:

name := """Scala_project"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.8"

libraryDependencies += jdbc
libraryDependencies += cache
libraryDependencies += ws
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test
libraryDependencies += "org.postgresql" % "postgresql" % "9.3-1100-jdbc4"
libraryDependencies += "com.typesafe.slick" %% "slick" % "3.0.0"
libraryDependencies += "org.slf4j" % "slf4j-nop" % "1.6.4"

And my table definition class:

package database;
//import scala.slick.driver.postgresdriver.simple._
import scala.concurrent.ExecutionContext.Implicits.global
import slick.driver.postgresdriver.api._
//import slick.backend.DatabaseConfig
import slick.driver.JdbcProfile
import models._



class EmployeesTableDef(tag: Tag) extends Table[Employee](tag, "employee_data") {

/*  val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("employee")
  import dbConfig.driver.api._  */

  def id = column[Long]("id", O.PrimaryKey,O.AutoInc)
  def name = column[String]("name")
  def resume = column[String]("resume")
  def additionalInformation = column[String]("additionalInformation")

  override def * =
    (id, name, resume, additionalInformation) <>(Employee.tupled, Employee.unapply)
}

Above example gives error:

object postgresdriver is not a member of package slick.driver

Because I couldn't find import which works i was trying to use dbConfig value, but the code let me use the import inside the class (not befeore it) so program still doesn't see the Table type.

Please, I would be very grateful for your help.

Upvotes: 0

Views: 326

Answers (1)

rogue-one
rogue-one

Reputation: 11587

Note: You can find a working sample project that uses the below strategy here

Dont use slick directly as a dependency. use play-slick which is a slick plugin for play.

libraryDependencies ++= Seq(
  "com.typesafe.play"   %%   "play-slick"              %   "2.0.0",
  "com.typesafe.play"   %%   "play-slick-evolutions"   %   "2.0.0"
)

You shouldn't directly import your postgres driver. This would introduce a hard dependency on postgres and hence your application would work only with postgres and you cannot use say H2 in dev/testing mode. The appropriate slick driver to be used should be dependency injected to avoid this hard dependency on postgres slick driver. The below example shows the implementation.

 trait EmployeeRepoHelper {

    self: HasDatabaseConfigProvider[JdbcProfile] => 

    import driver.api._

    lazy protected val employeeTableQuery = TableQuery[EmployeesTableDef]

    class EmployeesTableDef(tag: Tag) extends Table[Employee](tag, "employee_data") {

      def id = column[Long]("id", O.PrimaryKey,O.AutoInc)
      def name = column[String]("name")
      def resume = column[String]("resume")
      def additionalInformation = column[String]("additionalInformation")

      override def * =
        (id, name, resume, additionalInformation) <>(Employee.tupled, Employee.unapply)
    }

  }

With above definition. EmployeeRepository class which would provide interface for interacting with the database would look like below. Below I am using JIT binding of Guice DI framework which injects dbConfigProvider attribute. since EmployeeRepository take constructor parameters via dependency injection make sure your never instantiate the class by yourself but you always inject it in other classes.

class EmployeeRepository  @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)
  extends EmployeeRepoHelper
    with HasDatabaseConfigProvider[JdbcProfile] {

      import driver.api._

      def insert(employee: Employee) = db.run{
        employeeTableQuery += employee
      }

      /*
        Other methods for database interaction
      */
}

finally your application.conf should the connection information for your database. The below sample one uses H2 database connection details.

slick.dbs.default.driver="slick.driver.H2Driver$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play;MODE=MYSQL;DB_CLOSE_DELAY=-1"
slick.dbs.default.db.user=sa
slick.dbs.default.db.password=""

Upvotes: 2

Related Questions