Kotlin保存实体遇ObjectOptimisticLockingFailureException及Hibernate6.6 ID问题
问题分析与解决方案
问题根源
你遇到的ObjectOptimisticLockingFailureException本质是手动设置@Id字段和@GeneratedValue注解的冲突:
- 你给标注了
@GeneratedValue的uuid字段手动赋值UUID.randomUUID(),但该注解是让Hibernate自动生成主键的。 - Hibernate 6.6开始严格校验这种冲突场景,会误判该实体为已存在的记录,尝试执行更新而非插入,最终触发乐观锁异常。
解决步骤
修改实体类的UUID字段为可空类型
将val uuid: UUID改为val uuid: UUID?,这样创建实体时可以留空,让Hibernate负责生成主键值。修改后的实体代码:@Entity @Table(name = "customer") class Customer ( @Id @GeneratedValue @Column(name = "uuid", updatable = false) val uuid: UUID?, @Column(name = "first_name", nullable = false) var firstName: String )数据库中uuid字段作为主键本身是非空的,Hibernate生成主键后会自动填充,不会出现数据库空值问题。
创建实体时不再手动设置uuid
去掉手动生成UUID.randomUUID()的逻辑,构造实体时只传入firstName:return Customer( firstName = validatedCreationRequest.firstName?.value ?: "" )调用
customerRepository.save()时,Hibernate会自动生成UUID并赋值到实体的uuid字段,执行插入操作,避免之前的状态误判。
额外说明
不需要添加version字段,只要解决主键生成的冲突问题,乐观锁异常就会消失。
内容的提问来源于stack exchange,提问作者Kuldeep
相关产品推荐
相关产品推荐

