1

In the light of DRY, I'm trying to avoid the duplication of insert and update logic in Slick table definitions. I tried this:

trait Entity {
    def id: Option[Int]
}

case class BankRekening(id: Option[Int], nummer: String, omschrijving: String) extends Entity{
}

object BankRekeningen extends Table[BankRekening]("bankrekening") with InsertAndUpdate[BankRekening] {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def nummer = column[String]("nummer")
    def omschrijving = column[String]("omschrijving")
    def * = id.? ~ nummer ~ omschrijving <> (BankRekening, BankRekening.unapply _)
    def idx_nummer = index("idx_nummer", nummer, unique = true)
}

trait InsertAndUpdate[T <: Entity] {
    this: Table[T] =>

    def id: scala.slick.lifted.Column[Int]

    def insert(obj: T): T = {
        obj.copy(id = Some(this.returning(this.id) insert obj))
    }
}

Now the compiler complains about 'obj' in the last statement, saying: could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[T]

Any ideas?

4

1 回答 1

2

The simple answer: You try to call copy on T, which does not have a copy method.

The long answer: Unfortunately, Scalac, the Scala compiler let's Slick (unintendedly) high-jack the error message. You should have seen an error value copy is not a member of T. In case of copy Scalac somehow swallows that message because of the implicits Slick puts in scope. Here is a reduced reproduction:

object simple{
    implicit def intColumnType: TypedType[Int] = null
    implicit def valueToConstColumn[T : TypedType](v: T) = ConstColumn(v)
}
import simple._
trait TypedType[T]
case class ConstColumn[T](v: T){
  def bar = 5
}

trait InsertAndUpdate[T] {
    def insert(obj: T): T = {
      5.copy() // <- unexpected, but is valid and compiles fine
      5.bar    // compiles fine

      obj.bar    // error: value bar is not a member of type parameter T
                 // error: could not find implicit value for evidence parameter of type TypedType[T]

      obj.copy() // error: could not find implicit value for evidence parameter of type TypedType[T]
    }
}

As you can see the message is somehow swallowed for copy. Also I do not find the message could not find implicit value for evidence parameter of type TypedType[T] helpful. I created a Scala ticket to fix this: https://issues.scala-lang.org/browse/SI-7907

于 2013-10-12T13:33:13.117 回答