【发布时间】:2016-09-28 02:17:38
【问题描述】:
我有一个表单的架构:
CREATE TABLE definitions (
id BIGINT(20) AUTO_INCREMENT PRIMARY KEY,
json LONGTEXT NOT NULL
);
json 是我想返回给客户端的,它应该包括自动生成的id。
我想在单个事务中执行以下操作:
- 插入一个新行,其中
json不包含id;从插入中获取自动增量 ID。 - 更新同一行并将
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