Question

I am trying to write a generic CRUD trait for Slick 2.0. The trait should a) provide generic methods to read/update/delete entities as well as b) abstract from the database. Following this slick example (database abstraction) and this article (CRUD trait) I came up with the following (shortened) code snippet:

trait Profile {
  val profile: JdbcProfile
}

trait Crud[T <: AbstractTable[A], A] { this: Profile =>
  import profile.simple._

  val qry: TableQuery[T]

  def countAll()(implicit session: Session): Int = {
    qry.length.run
  }

  def getAll()(implicit session: Session): List[A] = {
      qry.list // <-- type mismatch; found: List[T#TableElementType] required: List[A]
  }
}

The code is invalid due to a type mismatch. The return type of the 2nd function seems to be of type List[T#TableElementType] but needs to be List[A]. Any ideas on how to solve the issue. Additional references to further readings on generic Slick 2.0 operations are welcome too.

Was it helpful?

Solution

type TableElementType is abstract inside of class AbstractTable[A]. Scala doesn't know about any relationship between A and TableElementType. class Table on the other hand defines final type TableElementType = A, which tells Scala about this relationship (and apparently Scala is smart enough to use the final annotation to know that the relationanship even holds for a subtype T <: Table[A] eventhough Table[A] is not co-variant in A).

So you need to use T <: Table[A] instead of T <: AbstractTable[A]. And because Table is inside the Slick driver cake (as in cake pattern), you need to move your Crud into your cake as well. Cakes are viral.

trait Profile {
  val profile: JdbcProfile
}
trait CrudComponent{ this: Profile =>
  import profile.simple._

  trait Crud[T <: Table[A], A] {

    val qry: TableQuery[T]

    def countAll()(implicit session: Session): Int = {
      qry.length.run
    }

    def getAll()(implicit session: Session): List[A] = {
        qry.list // <-- works as intended
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top