Slick 3.1.x Generic DAO for JdbcProfile 错误“值 id 不是...的成员”

Posted

技术标签:

【中文标题】Slick 3.1.x Generic DAO for JdbcProfile 错误“值 id 不是...的成员”【英文标题】:Slick 3.1.x Generic DAO for JdbcProfile error "value id is not a member of ..." 【发布时间】:2017-04-12 17:32:39 【问题描述】:

我正在尝试为我的 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]                                                                           ^

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

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,这很关键,因为人们过去曾实施过类似的解决方案,但它们在不同版本之间发生了相当大的变化。

【问题讨论】:

【参考方案1】:

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

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

而不是将ET 声明为Table[ER] 的子类型。将其声明为IdentifyableTable[PK] 的子类型。

像这样声明你的通用 dao

class GenericDao[PK, ER <: Identifyable[PK], ET <: IdentifyableTable[PK], TQ <: TableQuery[ET]] ....

【讨论】:

它很接近,但它并没有真正解决问题......例如,用户模型生成为class User(_tableTag: Tag) extends Table[UserRow],所以ET在这种情况下是User,它的id生成为@ 987654333@ @GiovanniAzua 您需要使用ET 类型使def id: Rep[PK] 可用。我不认为它是动态生成的【参考方案2】:

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

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

【讨论】:

第二个链接(“最终解决方案”)已损坏。如果你设法按时克隆它,你能把它放在 GitHub 上吗? 哈哈修复它......现在工作......我在泛型下重构了 dao 的泛型部分,仅此而已。实际上,您可以将整个代码复制粘贴到泛型下,因为不应该有任何其他依赖 谢谢!这就是我决定重写使用示例的原因...我只满足于完美:D 您还可以查看 dao 下的代码以获取示例扩展...我在 UserDao 扩展中专门介绍了许多 Slick 用例 这工作得很好,除了实体和可识别特征必须应用于模式代码生成器自动生成的所有表,这并不理想,所以我更喜欢用@987654325 混乱我自己的代码@无处不在。此外,由于缺少隐式(隐式真的很痛苦),我无法将 PK 类型 Long 替换为 Int,所以我将类型设为显式。但是你把我从绝望中救了出来。 @JulienD 在那个项目中我自定义了 slick 代码生成以生成所需的扩展等。这对我来说都是自动的。签出正在测试的链接项目 Generator.scala 文件

以上是关于Slick 3.1.x Generic DAO for JdbcProfile 错误“值 id 不是...的成员”的主要内容,如果未能解决你的问题,请参考以下文章

NullPointerException 使用 Spring 使 Generic Dao 休眠

Spring Generic Dao 类名

Scala + Play Framework + Slick - Json 作为模型字段

Slick Code 中的竞争条件

Hibernate Generic DAO - 测试生成的 SQL 是不是正确

Spring Hibernate:Generic Dao 添加原因 - org.hibernate.TransactionException:不支持嵌套事务