【问题标题】:Spring Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)Spring Row 被另一个事务更新或删除(或未保存值映射不正确)
【发布时间】:2019-06-01 07:11:10
【问题描述】:

我不明白,我的服务出了什么问题。我收到org.hibernate.StaleObjectStateException 尝试运行此方法:

fun updateNameForPhone(phone: String, name: String): Client {
    val res = clientRepository.findByPhone(phone) ?: throw ClientNotFoundException(phone)

    res.name = name
    return clientRepository.save(res)
}

客户端存储库:

@Repository
interface ClientRepository : JpaRepository<Client, UUID> {

    fun findByPhone(phone: String): Client?
}

客户实体:

@Entity
data class Client(
        var name: String = "",
        var phone: String = "",
        @Id @GeneratedValue(strategy = GenerationType.AUTO)
        val uuid: UUID = defaultUuid()
)

例外:

具有标识符的 [com.app.modules.client.domain.Client] 类的对象 [12647903-7773-4f07-87a8-e9f86e99aab3]:乐观锁定失败; 嵌套异常是 org.hibernate.StaleObjectStateException: Row was 由另一个事务更新或删除(或未保存值映射 不正确): [com.app.modules.client.domain.Client#12647903-7773-4f07-87a8-e9f86e99aab3]"

原因是什么? 我正在使用 Kotlin 1.3.11、Spring Boot 2.1.1、MySql。我不在不同的线程中运行它,只是尝试单个请求。

【问题讨论】:

  • 您能在这里分享一下您是如何定义交易的吗?
  • 另外,拥有数据库表结构也会很有帮助
  • 您得到一个乐观锁异常,但我没有看到您正在使用版本字段。你能把整个代码贴出来吗?
  • @simonmartinelli 我没有版本字段,还没有必要。
  • @ankur 我自己没有创建事务和表,它被 Spring 封装。我只是用实体注释标记我的客户端类。从 Controller 调用服务方法。那里没有有趣的代码。

标签: spring hibernate spring-boot kotlin


【解决方案1】:

好吧,我终于找到了解决方案。最好说解决方法。

问题在于 spring 使用 UUID 作为实体标识符的方式。 所以有两种解决方法,解决这个问题:

  • 首先,您可以将您的 id 字段类型更改为其他类型,例如 Long,如果您可以的话;
  • 或者您可以将此注释添加到您的uuid 字段:@Column(columnDefinition = "BINARY(16)")

我从this 问题中找到的最后一个解决方案。

【讨论】:

    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 2020-04-02
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2014-11-22
    • 2013-09-07
    相关资源
    最近更新 更多