You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slick中无需db.run与for推导式读取自增ID,关联表插入失败求助

解决Scala中插入主表后关联表无数据写入的问题

我来帮你拆解代码里的问题,再给出能正常运行的修复方案:

核心问题分析

  1. 不可变集合的误用:你定义的val transformedBookReaders = Seq[BookReaders]()是不可变的空序列,transformedBookReaders :+ ...只会返回一个新序列,不会修改原变量,导致action2始终对空序列执行插入操作。
  2. DBIO操作串联错误:action1.andThen(action2)只是按顺序执行两个独立的数据库操作,action2完全拿不到action1生成的自增ID和转换后的关联数据,两者没有依赖关系。

修正后的代码

def savebook(book: Book, bookReaders: Seq[BookReaders]) = {
  // 串联插入主表和关联表的操作,放在同一个事务里
  val transactionalAction = bookDAO.insertRow(book).flatMap { bookId =>
    // 用刚拿到的自增ID转换生成关联表对象
    val bookAssociations = bookReaders.map { bookReader =>
      BookAssociation(None, bookId, bookReader.moduleId, bookReader.userId, bookReader.roleId)
    }
    // 执行关联表批量插入
    bookAssocDao.insertRows(bookAssociations)
  }

  // 执行整个事务
  db.run(transactionalAction.transactionally)
}

关键改进说明

  • 用flatMap串联依赖操作:insertRow(book)返回的是DBIO[Long](假设自增ID为Long类型),通过flatMap可以在拿到bookId后直接生成并执行关联表的插入操作,让两个操作形成依赖关系,确保关联表能拿到正确的主表ID。
  • 去掉无效的中间变量:直接在flatMap内部生成关联表对象,避免了不可变集合赋值错误的问题。
  • 事务包裹全流程:整个链式操作被transactionally包裹,保证插入主表和关联表的操作要么全部成功,要么全部失败,维持数据一致性。

额外小提示

如果你的insertRows方法会返回受影响的行数,你也可以在flatMap末尾返回业务需要的结果(比如主表ID、关联表插入行数等),根据实际需求调整即可。

内容的提问来源于stack exchange,提问作者priyanka goel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:36:23