【问题标题】:How do I insert an object and use the auto-increment id to update the same object in a single slick transaction如何插入一个对象并使用自动增量 id 在单个光滑事务中更新同一个对象
【发布时间】:2016-09-28 02:17:38
【问题描述】:

我有一个表单的架构:

CREATE TABLE definitions (
  id BIGINT(20) AUTO_INCREMENT PRIMARY KEY,
  json LONGTEXT NOT NULL
);

json 是我想返回给客户端的,它应该包括自动生成的id

我想在单个事务中执行以下操作:

  1. 插入一个新行,其中json 不包含id;从插入中获取自动增量 ID。
  2. 更新同一行并将json 替换为包含id 的新对象。

光滑的文档向我展示了如何获取自动增量 ID,但我不知道如何编写查询/插入以在单个事务中执行这两个操作。

// TableQuery object for my table
class Definitions(driver: RelationalDriver, tag: Tag) extends ... {
  import driver.api._ 

  // implicit conversion for Definition
  private implicit val definitionToJson =
    MappedColumnType.base[Definition, String](
     { definition => definitionToJson(definition) },
     { json => definitionFromJson(json) }
  )

  def id: slick.lifted.Rep[Long] =
    column[Long](
      "id", 
      ColumnOption.PrimaryKey,
      ColumnOption.AutoInc
    )

  def json: slick.lifted.Rep[Definition] =     
    column[Definition]("json")

  override def * = (
    id,
    json
  ) <> (DefinitionRow.tupled, DefinitionRow.unapply)
}

class Dao {

  // ...

  // operation 1: insert row, and get back auto-increment id
  // definitions is an instance of above
  val op1 = (definitions returning definitions.map(_.id)) += json

  // operation 2: find the inserted row and update the object
  val op2 = op1.flatMap(insertId =>
    definitions.filter(_.id === insertId)
               .map(_.json)
               .update(updatedJson(insertId))

  // run both in a transaction
  db.run(op2.transactionally)
}

op2 拒绝编译。

[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[Definition]
[error]    Unpacked type: T
[error]      Packed type: G
[error]       val op2 = op1.flatMap(autoIncId =>   
                correlationDefinitionSlick.filter(_.id ===
                autoIncId.get).map(_.json).update(json))

说实话,我不明白为什么它不能映射请求的类型。

编辑:我通过在我的 DAO 中重新定义隐式转换来完成上述工作,但我不明白我为什么需要这样做。

【问题讨论】:

    标签: slick


    【解决方案1】:

    Slick 查询需要范围内的隐式映射

    您收到此编译器错误,因为您将表内的隐式定义映射声明为私有,并且无法访问查询您使用定义的位置。

    将您的代码移动到 Container 类中并在 Table 之外声明隐式光滑映射

    class Container(driver: RelationalDriver) {
    
          import driver.api._ 
        // implicit conversion for Definition
          private implicit val definitionToJson =
            MappedColumnType.base[Definition, String](
             { definition => definitionToJson(definition) },
             { json => definitionFromJson(json) }
          )
    
            class Definitions(driver: RelationalDriver, tag: Tag) extends ... {
    
    
    
          def id: slick.lifted.Rep[Long] =
            column[Long](
              "id", 
              ColumnOption.PrimaryKey,
              ColumnOption.AutoInc
            )
    
          def json: slick.lifted.Rep[Definition] =     
            column[Definition]("json")
    
          override def * = (
            id,
            json
          ) <> (DefinitionRow.tupled, DefinitionRow.unapply)
        }
    
        class Dao {
    
          // ...
    
          // operation 1: insert row, and get back auto-increment id
          // definitions is an instance of above
          val op1 = (definitions returning definitions.map(_.id)) += json
    
          // operation 2: find the inserted row and update the object
          val op2 = op1.flatMap(insertId =>
            definitions.filter(_.id === insertId)
                       .map(_.json)
                       .update(updatedJson(insertId))
    
          // run both in a transaction
          db.run(op2.transactionally)
        }
    
    }
    

    【讨论】:

    • 嗯。我不能这样做,因为MappedColumnType 是一种只能通过从driver 导入的类型。此外,我更好奇为什么我需要在我的 DAO 和表中进行隐式转换?另外,FlatShapeLevel 到底是什么?
    • @AllenGeorge 编辑了答案......相信我这行得通
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多