Spring Row 已被另一个事务更新或删除(或未保存值映射不正确)

Kam*_*ian 3 spring hibernate kotlin spring-boot

我不明白,我的服务出了什么问题。我收到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)
}
Run Code Online (Sandbox Code Playgroud)

客户端存储库:

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

    fun findByPhone(phone: String): Client?
}
Run Code Online (Sandbox Code Playgroud)

客户实体:

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

例外:

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

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

Kam*_*ian 5

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

问题在于 spring 使用UUID实体标识符的方式。因此有两种解决方法可以解决这个问题:

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

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