问题描述
我的表在我的 postgresql 数据库中的一对列上有一个唯一索引.
My table has a unique index on a pair of columns in my postgresql database.
我想知道如何在插入时捕获重复的键异常:
I want to know how I can catch a duplicate key exception when I am inserting:
def save(user: User)(implicit session: Session): User = {
val newId = (users returning users.map(_id) += user
user.copy(id = newId)
}
我的日志显示此异常:
Execution exception[[PSQLException: ERROR: duplicate key value violates unique constraint "...."
我也没有真正在 Scala 中使用过异常.
I haven't really used exceptions much in scala either yet also.
推荐答案
您的 save
方法可能应该返回与 User
不同的内容,以指示失败的可能性.如果唯一会抛出的异常是唯一键,并且您真的只关心成功或失败(而不是失败的类型),那么一种方法是返回 Option[User]
.
Your save
method should probably return something different than just User
, to indicate the possibility of failure. If the only exception that will be thrown is by unique key, and you really only care about success or failure (and not the type of failure), one way to go would be to return Option[User]
.
你可以使用一个简单的 try/catch
块,将成功的保存映射到 Some[User]
和 PSQLException
到 None代码>:
You could use a simple try/catch
block, mapping successful saves to Some[User]
and PSQLException
to None
:
def save(user: User)(implicit session: Session): Option[User] = {
try {
val newId = (users returning users.map(_id) += user
Some(user.copy(id = newId))
} catch {
case PSQLException => None
}
}
我个人不是这样的,因为 try/catch
并不是真正惯用的 Scala,并且您的错误类型被丢弃.下一个选项是使用 scala.util.Try
.
Personally not the way I'd go, as try/catch
isn't really idiomatic Scala, and your error type is discarded. The next option is to use scala.util.Try
.
def save(user: User)(implicit session: Session): Try[User] = Try {
val newId = (users returning users.map(_id) += user
user.copy(id = newId)
}
这里的代码更简单.如果Try
的body成功,则save
返回Success[User]
,否则返回包裹在失败代码>.这将允许您使用 Try
做很多事情.
The code here is simpler. If the body of Try
is successful, then save
will return Success[User]
, and if not it will return the exception wrapped in Failure
. This will allow you to do many things with Try
.
您可以进行模式匹配:
save(user) match {
case Success(user) => Ok(user)
case Failure(t: PSQLException) if(e.getSQLState == "23505") => InternalServerError("Some sort of unique key violation..")
case Failure(t: PSQLException) => InternalServerError("Some sort of psql error..")
case Failure(_) => InternalServerError("Something else happened.. it was bad..")
}
你可以像Option
一样使用它:
save(user) map { user =>
Ok(user)
} getOrElse {
InternalServerError("Something terrible happened..")
}
您可以一次将多个组合在一起,并在第一次失败时停止:
You can compose many together at once, and stop on the first failure:
(for {
u1 <- save(user1)
u2 <- save(user2)
u3 <- save(user3)
} yield {
(u1, u2, u3)
}) match {
case Success((u1, u2, u3)) => Ok(...)
case Failure(...) => ...
}
这篇关于如何捕获重复键值违规的光滑 postgres 异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!