如何使用 play2.6 slick3 更新 sql 服务器的身份列?
How to update the sql server's identity column using play2.6 slick3?
当我尝试使用 sql 服务器 运行 sbt scala 项目时出现以下错误,
[SQLServerException: 无法更新标识列 'ID'。]
我正在使用 Play 2.6、Scala 2.12、Slick 3
我的更新函数是,
def update(id: Long): Action[AnyContent] = Action.async { implicit request =>
topicForm.bindFromRequest.fold(
formWithErrors => Future.successful(BadRequest(html.editForm(id, formWithErrors))),
topic => {
val futureTopUpdate = dao.update(id, topic.copy(id = Some(id)))
futureTopUpdate.map { result =>
Home.flashing("success" -> "Topic %s has been updated".format(topic.code))
}.recover {
case ex: TimeoutException =>
Logger.error("Problem found in topic update process")
InternalServerError(ex.getMessage)
}
})
}
和 DAO:
override def update(id: Long, topic: Topic): Future[Int] =
try db.run(filterQuery(id).update(topic))
finally db.close
有什么想法吗?
您可以展示 filterQuery(id) 实现,我们的 dao 中类似的东西以这种方式运行良好:
override def update(id: Long, topic: Topic): Future[Int] = {
db.run(filterQuery(id).update(topic.copy(id))
}
通知: topic.copy(id)
filterQuery 是:
def filterQuery(id: Int) = themes.filter(_.id === id)
我们使用 Play 2.6、Scala 2.12、Slick 3 MYSQL。
更新#1:
-> 实体:
case class CategoryRow(id: Int, name: String, description: String)
-> 映射:
trait CategoryMapping {
self: HasDatabaseConfigProvider[JdbcProfile] =>
import dbConfig.profile.api._
private[models] class CategoryTable(tag: Tag)
extends Table[CategoryRow](tag, "category") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name", O.Length(TextMaxLength_250))
def description = column[String]("description", Nullable)
def categoryNameAgencyIndex = index("categoryName_agency_idx", (name, agencyId), unique = true)
override def * = (
id,
name,
description
) <> (CategoryRow.tupled, CategoryRow.unapply)
}
private[models] val Categories = TableQuery[CategoryTable]
private[models] val CategoriesInsertQuery = Categories returning Categories.map(_.id)
}
-> 回购
trait CategoryRepository {
//...
def update(id: Int, category: Category)(implicit agencyId: Int): Future[Int]
//...
}
-> REPOImpl:
@Singleton
class CategoryRepositoryImpl @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit ec: RepositoryExecutionContext)
extends CategoryRepository with HasDatabaseConfigProvider[JdbcProfile] with CategoryMapping {
import dbConfig.profile.api._
//....
def update(id: Int, category: CategoryRow)(implicit agencyId: Int): Future[Int] =
db.run(filter(id).update(category.copy(id)))
private def filter(id: Int) = Categories.filter(_.id === id)
//....
}
-> RepositoryExecutionContex
class RepositoryExecutionContext @Inject()(actorSystem: ActorSystem) extends CustomExecutionContext(actorSystem, "repository.dispatcher")
和aplication.conf:
# db connections = ((physical_core_count * 2) + effective_spindle_count)
fixedConnectionPool = 5
repository.dispatcher {
executor = "thread-pool-executor"
throughput = 1
thread-pool-executor {
fixed-pool-size = ${fixedConnectionPool}
}
}
Chapter 3.3 of Essential Slick 中有更多关于折叠的信息。
当我尝试使用 sql 服务器 运行 sbt scala 项目时出现以下错误,
[SQLServerException: 无法更新标识列 'ID'。]
我正在使用 Play 2.6、Scala 2.12、Slick 3
我的更新函数是,
def update(id: Long): Action[AnyContent] = Action.async { implicit request =>
topicForm.bindFromRequest.fold(
formWithErrors => Future.successful(BadRequest(html.editForm(id, formWithErrors))),
topic => {
val futureTopUpdate = dao.update(id, topic.copy(id = Some(id)))
futureTopUpdate.map { result =>
Home.flashing("success" -> "Topic %s has been updated".format(topic.code))
}.recover {
case ex: TimeoutException =>
Logger.error("Problem found in topic update process")
InternalServerError(ex.getMessage)
}
})
}
和 DAO:
override def update(id: Long, topic: Topic): Future[Int] =
try db.run(filterQuery(id).update(topic))
finally db.close
有什么想法吗?
您可以展示 filterQuery(id) 实现,我们的 dao 中类似的东西以这种方式运行良好:
override def update(id: Long, topic: Topic): Future[Int] = {
db.run(filterQuery(id).update(topic.copy(id))
}
通知: topic.copy(id)
filterQuery 是:
def filterQuery(id: Int) = themes.filter(_.id === id)
我们使用 Play 2.6、Scala 2.12、Slick 3 MYSQL。
更新#1:
-> 实体:
case class CategoryRow(id: Int, name: String, description: String)
-> 映射:
trait CategoryMapping {
self: HasDatabaseConfigProvider[JdbcProfile] =>
import dbConfig.profile.api._
private[models] class CategoryTable(tag: Tag)
extends Table[CategoryRow](tag, "category") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name", O.Length(TextMaxLength_250))
def description = column[String]("description", Nullable)
def categoryNameAgencyIndex = index("categoryName_agency_idx", (name, agencyId), unique = true)
override def * = (
id,
name,
description
) <> (CategoryRow.tupled, CategoryRow.unapply)
}
private[models] val Categories = TableQuery[CategoryTable]
private[models] val CategoriesInsertQuery = Categories returning Categories.map(_.id)
}
-> 回购
trait CategoryRepository {
//...
def update(id: Int, category: Category)(implicit agencyId: Int): Future[Int]
//...
}
-> REPOImpl:
@Singleton
class CategoryRepositoryImpl @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit ec: RepositoryExecutionContext)
extends CategoryRepository with HasDatabaseConfigProvider[JdbcProfile] with CategoryMapping {
import dbConfig.profile.api._
//....
def update(id: Int, category: CategoryRow)(implicit agencyId: Int): Future[Int] =
db.run(filter(id).update(category.copy(id)))
private def filter(id: Int) = Categories.filter(_.id === id)
//....
}
-> RepositoryExecutionContex
class RepositoryExecutionContext @Inject()(actorSystem: ActorSystem) extends CustomExecutionContext(actorSystem, "repository.dispatcher")
和aplication.conf:
# db connections = ((physical_core_count * 2) + effective_spindle_count)
fixedConnectionPool = 5
repository.dispatcher {
executor = "thread-pool-executor"
throughput = 1
thread-pool-executor {
fixed-pool-size = ${fixedConnectionPool}
}
}
Chapter 3.3 of Essential Slick 中有更多关于折叠的信息。