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

Slick:获取插入记录ID时返回Future而非预期ID的问题咨询

Why am I getting a Future instead of the inserted row ID with Slick 3.0?

It looks like you've got the core insertion logic right—your row is being created in the database, which means the returning clause and insertion setup are working as expected. The confusion comes down to how Slick 3.x handles database operations.

Your Code Recap

Here's the code you shared for context:

var point = TableQuery[Geopointtable]
val writeQuery = point returning point.map(_.id)
val geoId = writeQuery += GeopointtableRow(0, 50, 40)
val idFromDb = db.run(geoId)

Why You're Getting a Future

Slick 3.x was designed with asynchronous IO in mind—all database operations return a Future[T] instead of blocking and returning the result directly. This is a deliberate choice to avoid tying up application threads waiting for slow database calls.

In your case, db.run(geoId) returns a Future[Long] (assuming your id column is a Long type) that will eventually hold the inserted ID once the database operation completes. The Future() you're seeing is just the uncompleted state of this asynchronous computation.

How to Get the Actual Inserted ID

You have two main options depending on your application's environment:

1. Handle Asynchronously (Recommended for Production)

If you're working in an asynchronous context (like a Play Framework app or any non-blocking service), use map or flatMap to process the result once the Future completes:

import scala.concurrent.ExecutionContext.Implicits.global // Use your app's dedicated EC in production

val idFromDb: Future[Long] = db.run(geoId)

// Process the ID once it's available
idFromDb.map { insertedId =>
  println(s"Successfully inserted row with ID: $insertedId")
  // Add your business logic here (e.g., update other tables, return a response)
}

Note: Always use your application's dedicated ExecutionContext instead of the global one in production to avoid thread pool issues.

2. Block to Get the Result (For Testing/Console Apps Only)

If you're in a synchronous environment (like a simple console script or unit test), you can use Await.result to block until the Future completes. Never do this in production—it defeats the purpose of asynchronous IO and can hurt performance:

import scala.concurrent.Await
import scala.concurrent.duration._

val insertedId = Await.result(idFromDb, 5.seconds) // Wait up to 5 seconds for the result
println(s"Inserted ID: $insertedId")

Quick Check: Your Insert Logic is Correct

Just to confirm—your use of returning point.map(_.id) is exactly the right way to get the auto-generated ID from an insert in Slick 3.0. The only issue was misunderstanding the asynchronous nature of Slick's database calls.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:27:50