【问题标题】:Play Slick handling Date with matching Shapes and Implicits使用匹配的 Shapes 和 Implicits 玩 Slick 处理日期
【发布时间】:2016-06-27 15:16:10
【问题描述】:

我正在向 Person 表添加两个附加字段:一个日期和一个字符串。我按照olivebh's tutorial 构建了 Person 表并使用 Play Slick 映射它。 但是,我从 Slick 数据模型特征表中得到以下错误:

dao/Tables.scala:85: ambiguous implicit values:
[error]  both value e3 of type slick.jdbc.GetResult[String]
[error]  and value e1 of type slick.jdbc.GetResult[String]
[error]  match expected type slick.jdbc.GetResult[String]
[error]       ProjectRow.tupled((<<[Int], <<[String], <<[Date], <<[String]))

指的是以下行:

  implicit def GetResultPersonRow(implicit e0: GR[Int], e1: GR[String], e2: GR[Date], e3: GR[String]): GR[ProjectRow] = GR {
prs =>
  import prs._
  PersonRow.tupled((<<[Int], <<[String], <<[Date], <<[String]))

}

其中“int、string、date、string”分别代表“id、name、birthdate、language”字段。按照以“id,name”为例的教程,一切正常。但是一旦我添加了生日和语言,我就得到了上面引用的错误。

另外,在为表格行创建原型时:

  class Person(_tableTag: Tag) extends Table[PersonRow](_tableTag, "person") {
    def * = (personId, name, birthdate, language) <>(PersonRow.tupled, PersonRow.unapply)

    def ? = (Rep.Some(personId), Rep.Some(name), Rep.Some(birthdate), Rep.Some(language)).shaped.<>({ r => import r._; _1.map(_ => ProjectRow.tupled((_1.get, _2.get, _3.get, _4.get))) }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

    val personId: Rep[Int] = column[Int]("person_id", O.AutoInc, O.PrimaryKey)
    val name: Rep[String] = column[String]("name", O.Length(50, varying = true))
    val birthdate: Rep[Date] = column[Date]("birthdate", O.Length(50, varying = true))
    val language: Rep[String] = column[String]("language", O.Length(50, varying = true))

我收到以下错误:

No matching Shape found.
[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
[error]   Required level: slick.lifted.FlatShapeLevel
[error]      Source type: (slick.lifted.Rep[Int], slick.lifted.Rep[String], slick.lifted.Rep[java.util.Date], slick.lifted.Rep[String])
[error]    Unpacked type: (Int, String, java.util.Date, String)
[error]      Packed type: Any
[error]     def * = (personId, name, birthdate, language) <>(PersonRow.tupled, PersonRow.unapply)

还有:

dao/Tables.scala:94: could not find implicit value for parameter od: slick.lifted.OptionLift[Tables.this.driver.api.Rep[java.util.Date],O]
[error]     def ? = (Rep.Some(personId), Rep.Some(name), Rep.Some(birthdate), Rep.Some(language)).shaped.<>({ r => import r._; _1.map(_ => PersonRow.tupled((_1.get, _2.get, _3.get, _4.get))) }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))
dao/Tables.scala:94: not found: value _1
[error]     def ? = (Rep.Some(personId), Rep.Some(name), Rep.Some(birthdate), Rep.Some(language)).shaped.<>({ r => import r._; _1.map(_ => PersonRow.tupled((_1.get, _2.get, _3.get, _4.get))) }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

任何有助于理解这些错误以及如何更改Slick data model trait 以使其正确处理两个额外的日期和字符串字段,将不胜感激。非常感谢!

【问题讨论】:

    标签: scala playframework slick


    【解决方案1】:

    Slick 无法处理 java.util.Date,因为数据库只能通过 JDBC 驱动程序理解 java.sql.Date。你可以制作自己的映射器,这样 Slick 就可以知道如何读/写java.util.Date/java.sql.Date。但是,Java 8 现在有一个更好的 API 来处理日期/时间/日历。

    implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, Timestamp](
        ldt => Timestamp.valueOf(ldt),
        t => t.toLocalDateTime
    )
    

    另请参阅this 问题。顺便说一句,感谢您阅读我的文章,希望它有用! :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多