1

我正在尝试为我的 slick 代码生成模型创建一个 Slick 3.1.1 Generic DAO。但是,我面临最后一个无法找到解决方法的编译错误。

整个项目在 GitHub play-authenticate-usage-scala中可用,相关源代码在GenericDao.scala中。

编译器错误如下:

[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]                                                                           ^

基本上它不识别特征id下的定义Identifyable。最重要的声明如下:

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:请注意,我正在使用最新的 Slick 3.1.1,这很关键,因为人们过去曾实施过类似的解决方案,但它们在不同版本之间发生了相当大的变化。

4

2 回答 2

2

ET是一个表(的子类型Table[ER])。从错误中可以清楚地看出ET没有Rep[PK]

trait IdentifyableTable[PK] extends Table[ER] {
  def id: Rep[PK]
}

而不是声明ETTable[ER]. 将其声明为 的子类型IdentifyableTable[PK]

像这样声明你的通用 dao

class GenericDao[PK, ER <: Identifyable[PK], ET <: IdentifyableTable[PK], TQ <: TableQuery[ET]] ....
于 2016-11-28T21:28:46.297 回答
1

我发现以前的 Slick 版本CrudComponent gist 实现不能完全按原样采用,但通过将其调整为最新的 Slick 3.1.x,它然后解决id了 OP 中描述的编译问题。解决方案基本上是重新排列模板类型及其边界。

最终解决方案可以在文件GenericDao.scala中找到

于 2016-11-29T11:03:29.020 回答