scalaslickplay-slickgenericdao

Slick 3.1.x Generic DAO for JdbcProfile error "value id is not a member of ..."


I'm trying to create a Slick 3.1.1 Generic DAO for my slick code-generated model. However, I'm facing one last compilation error that can't find how to fix.

The whole project is available in GitHub play-authenticate-usage-scala and the relevant source code is in the GenericDao.scala.

The compiler error is the following:

[info] Compiling 16 Scala sources and 1 Java source to /home/bravegag/code/play-authenticate-usage-scala/target/scala-2.11/classes...
[error] /home/bravegag/code/play-authenticate-usage-scala/app/dao/GenericDao.scala:46: value id is not a member of type parameter ET
[error]     def findById(id: PK): Future[Option[ER]] = db.run(tableQuery.filter(_.id === id).result.headOption)
[error]                                                                           ^

Basically it doesn't recognize the id definition under the Identifyable trait. The top declarations are the following:

trait Identifyable[PK] extends Product {
  def id : PK
}

trait GenericDaoHelper {
  val profile: slick.driver.JdbcProfile
  import profile.api._

  class GenericDao[PK, ER <: Identifyable[PK], ET <: Table[ER], TQ <: TableQuery[ET]] @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
      (tableQuery: TQ) extends HasDatabaseConfigProvider[JdbcProfile] {
    import driver.api._

    /**
      * Returns the matching entity for the given id
      * @param id identifier
      * @return the matching entity for the given id
      */
    def findById(id: PK): Future[Option[ER]] = db.run(tableQuery.filter(_.id === id).result.headOption)
}

PS: note that I'm working with the latest Slick 3.1.1 this is critical because people have implemented similar solutions in the past but they change quite a bit from version to version.


Solution

  • I found a previous Slick version CrudComponent gist implementation that can't be taken exactly as is but by adapting it to the latest Slick 3.1.x it then solves the id compilation issue described in the OP. The solution was basically a rearrangement of the template types and their bounds.

    The final solution can be found in file GenericDao.scala