如何修复INSERT上返回的单个AutoInc列的Slick Exception

时间:2017-10-14 17:14:49

标签: mysql scala slick slick-3.0

我试图实现提供的akka​​-http rest示例 this thread  但是我坚持

-Dfile.encoding=MS950 -Duser.language=zh -Duser.country=TW -Dsun.jnu.encoding=MS950

这是Scala代码: 注册API:

    slick.SlickException: This DBMS allows only a single column to be returned from an INSERT, and that column must be an AutoInc column.
    at slick.jdbc.JdbcStatementBuilderComponent$JdbcCompiledInsert.buildReturnColumns(JdbcStatementBuilderComponent.scala:67)

AuthService.scala

path("signUp") {
    pathEndOrSingleSlash {
      post {
        entity(as[UsernamePasswordEmail]) { userEntity =>
          complete(Created -> signUp(userEntity.username, userEntity.email, userEntity.password))
        }
      }
    }
  }

AuthDataStorage.scala

def signUp(login: String, email: String, password: String): Future[AuthToken] =
    authDataStorage
      .saveAuthData(AuthData(UUID.randomUUID().toString, login, email, password.sha256.hex))
      .map(authData => encodeToken(authData.id))

由于我是Scala和Slick的新手,无论如何都可以提供为什么发生此异常的信息,即使我已经在模型中定义了... override def saveAuthData(authData: AuthData): Future[AuthData] = db.run((auth returning auth).insertOrUpdate(authData)).map(_ => authData) ... 。我正在使用MySQL RDBMS

2 个答案:

答案 0 :(得分:0)

问题在于returning auth。只需返回自动增量标识auth,而不是返回id即完整对象。 Slick不支持返回整个对象,尽管它正确编译。它不会生成有效的SQL查询。

一旦您可以访问自动增量id,就可以使用函数的参数构建AuthData

代码:

(auth returning auth.map(_.id)).insertOrUpdate(authData)).map(id => authData.copy(id = id))

答案 1 :(得分:0)

异常是MySQL行为的结果。正如Slick documentation所述:

  

许多数据库系统只允许返回单个列,该列必须是表的自动递增主键。如果要求其他列,则在运行时抛出Seq A B C 1 0.3 0.5 0.6 2 NaN 0.9 1.0 3 1.2 NaN 1.5 (除非数据库实际支持它)。

更改SlickException方法以在upsert上返回saveAuthData列:

id

在上面的代码中,override def saveAuthData(authData: AuthData): Future[AuthData] = db.run((auth returning auth.map(_.id)).insertOrUpdate(authData)) .map(idFromDb => authData.copy(id = idFromDb.getOrElse(authData.id))) 是插入的idFromDb和更新的Some[Int]