2
votes

I've been trying to use Slick using the generic JdbcDriver and have run into a Scala type mismatch error. If I try this without Slick and roll-my-own super simple Table & TableQuery mocks the problem does not occur, so believe the error's related to some of Slick's more sophisticated use of Scala.

The example below uses Slick 3.1.1. I've also tried the equivalent with Slick 3.2.0-M1 (changing driver to profile where necessary), but the same error is present.

There appear to be a number of 'type mismatch' questions/answers on StackOverflow, but I can't interpret if they are related to this issue, so any help improving my Scala/Slick usage is appreciated.

The following code produces:

*Error:(37, 25) type mismatch;
 found   : slick.lifted.TableQuery[dao.PersonTable]
 required: slick.lifted.TableQuery[_ <: _2.driver.Table[_]] where val _2: test.Test.ProfileUser
    dbDriver.create(dao.persons) // Creates this error...*

package test

import slick.backend.DatabaseConfig
import slick.driver.JdbcDriver

trait GenericDriver {
  val driver: JdbcDriver
}

case class PersonRecord(id: Int, name: String)

trait Person {
  self: GenericDriver =>

  import driver.api._

  class PersonTable(tag: Tag) extends Table[PersonRecord](tag, "persons") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def name = column[String]("name")
    def * = (id, name) <> (PersonRecord.tupled, PersonRecord.unapply)
  }

  val persons = TableQuery[PersonTable]
}

class Dao(val driver: JdbcDriver)
  extends Person
    with GenericDriver

object Test {

  def main(args: Array[String]): Unit = {
    val dbConfig = DatabaseConfig.forConfig[JdbcDriver]("sampleDb")
    val dbDriver = dbConfig.driver
    val dao = new Dao(dbDriver)

    dbDriver.create(dao.persons) // Creates this error...
    //
    //    Error:(37, 25) type mismatch;
    //    found   : slick.lifted.TableQuery[dao.PersonTable]
    //    required: slick.lifted.TableQuery[_ <: _2.driver.Table[_]] where val _2: test.Test.ProfileUser
    //    dbDriver.create(dao.persons) // Creates this error...
    //
  }

  implicit class ProfileUser(val driver: JdbcDriver) extends GenericDriver {
    import driver.api._
    def create(tq: TableQuery[_ <: Table[_]]) = tq.schema.create
  }

}

For info - build.sbt is:

name := "test_import"

version := "1.0"

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.typesafe.slick" %% "slick" % "3.1.1"
)
1
I have also tried this using import driver.profile.api._. This produces a similar error message however: Error:(37, 25) type mismatch; found : dao.driver.profile.api.TableQuery[_$1] where type _$1 <: dao.driver.profile.api.Table[_] (which expands to) slick.lifted.TableQuery[_$1] required: slick.lifted.TableQuery[_ <: _2.driver.profile.Table[_]] where val _2: test.Test.ProfileUser dbDriver.create(dao.persons)Nigel Eke

1 Answers

1
votes

The issue here turns out to be Path Dependent Types.

This (StackOverflow) Q&A helped guide me in the right direction: Scala Type Mismatch issue when using import from different scope.

And this (External) article helped with further understanding of PDT: http://danielwestheide.com/blog/2013/02/13/the-neophytes-guide-to-scala-part-13-path-dependent-types.html