【问题标题】:scala slick 2.0.2 cannot automatic map to custom classscala slick 2.0.2 无法自动映射到自定义类
【发布时间】:2014-06-01 04:00:01
【问题描述】:

我开始使用 Slick,但我不知道如何将查询结果映射到我的自定义案例类上。 这是我的代码:

package main.scala.model.Tree

import scala.slick.driver.H2Driver.simple._

case class SlickNode(id : Long, parentId : Long, stateString : String) 
    extends AbstractNode{}

object SlickNode {
    val nodes = TableQuery[SlickNodes]
    def findById(x : Long) : SlickNode = nodes.filter(_.id == x).first
    def findByParentId(x : Long) : Iterable[SlickNode] = nodes.filter(_.parentId == x).list

}

class SlickNodes(tag: Tag) extends Table[(Long, Long, String)](tag, "NODES") {
    def id = column[Long]("NODE_ID", O.PrimaryKey, O.AutoInc)
    def parentId = column[Long]("PARENT")
    def stateString = column[String]("STATE")
    def * = (id, parentId, stateString) <> ((SlickNode.apply _).tupled , SlickNode.unapply)
}

我所期望的是从 (Long, Long, String) 到 SlickNode 的自动转换,如 * 定义中所述。 我错过了什么吗? 先感谢您。 亲切的问候

********* 编辑 ********* 我认为问题在我的代码中更深层次。 当我尝试编译它时,我得到了这个错误:

[error] 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: scala.slick.lifted.ShapeLevel.Flat
[error]      Source type: scala.slick.lifted.MappedProjection[main.scala.model.Tree.SlickNode,(Long, Long, String)]
[error]    Unpacked type: (Long, Long, String)
[error]      Packed type: Any
[error]   def * = (id, parentId, stateString) <> ((SlickNode.apply _).tupled , SlickNode.unapply)
[error]                                       ^

【问题讨论】:

  • 我认为问题在我的代码中更深层次。当我尝试编译它时,我收到此错误:未找到匹配的形状。 Slick 不知道如何映射给定的类型。可能的原因: Table[T] 中的 T 与您的 * 投影不匹配。或者您在查询中使用不受支持的类型(例如 scala 列表)。所需级别:scala.slick.lifted.ShapeLevel.Flat 源类型:scala.slick.lifted.MappedProjection[main.scala.model.Tree.SlickNode,(Long, Long, String)] 解压类型:(Long, Long, String ) 打包类型:任意 def * = (id, parentId, stateString) ((SlickNode.apply _).tupled , SlickNode.unapply)

标签: scala mapping slick


【解决方案1】:

问题是您正在扩展一个三元表,而不是SlickNodeRow 的表:

class AbstractNode

case class SlickNodeRow(id : Long, parentId : Long, stateString : String) extends AbstractNode

object SlickNode {
  val nodes = TableQuery[SlickNodes]
  def findById(x : Long)(implicit s: Session): Option[SlickNodes#TableElementType] = nodes.filter(_.id === x).firstOption
  def findByParentId(x : Long) : Iterable[SlickNodeRow] = nodes.filter(_.parentId == x).list
}

class SlickNodes(tag: Tag) extends Table[SlickNodeRow](tag, "NODES") {
                                             * here   
  def id = column[Long]("NODE_ID", O.PrimaryKey, O.AutoInc)
  def parentId = column[Long]("PARENT")
  def stateString = column[String]("STATE")
  def * = (id, parentId, stateString) <> ((SlickNodeRow.apply _).tupled , SlickNodeRow.unapply)
}

投影函数不知道如何将三元组映射到 SlickNodeRow 案例类。如果你想返回三倍,你的代码应该是这样的:

class Suppliers(tag: Tag) extends Table[(Int, String, String)](tag, "SUPPLIERS") {
  def id = column[Int]("SUP_ID", O.PrimaryKey)
  def name = column[String]("SUP_NAME")
  def street = column[String]("STREET")
  def * = (id, name, street)
}
val suppliers = TableQuery[Suppliers]

As shown here,投影不返回一个案例类,而是一个三元组。也许你可以编写你的投影方法,让它从一个三元组返回一个SlickNodeRow,不过我不确定。

【讨论】:

  • 我太想念它了...我知道有类似的东西..但无法弄清楚...非常感谢!
  • 我添加了一个示例,说明如果您不想使用案例类,如何返回三元组。
猜你喜欢
  • 1970-01-01
  • 2017-04-22
  • 2017-10-11
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多