Spring JPA带id保存时报错:detached entity passed to persist

问题:

因项目JDK升级从11升到21,相应的Spring从2.x升级到3.x,Hiberante也从5.x升级到6.6. 然后在测试时发现如下代码报错

实体类User对应表users

java 复制代码
@Data
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(generator = "customerUUIDGenerator")
    @GenericGenerator(
            name = "customerUUIDGenerator",
            strategy = "org.example.id.customerUUIDGenerator"
    )
    private UUID id;

    @Version
    private int version;

    @Column(unique = true, nullable = false)
    private String username;

}

自定义id生成器

java 复制代码
public class CustomerUUIDGenerator implements IdentifierGenerator {
    
    @Override
    public Object generate(SharedSessionContractImplementor session, Object object) {
        final EntityPersister entityPersister = session.getEntityPersister( null, object );
		Object id = entityPersister.getIdentifier( object, session );
        return null != id ? id : UUID.randomUUID();
    }
}

代码中存在如下使用

java 复制代码
    ...
    public void addUser(UUID id, String name, String passwd) {
        User user = new User();
        user.setId(id);
        user.setUsername(name);
        userRepository.save(user);
        
    }

上面代码报错: detached entity passed to persist 或者StaleObjectStateException

原因

Hibernate在保存时会先查数据库有没有该数据

如果无则判断实体是否新创建的,判断流程主要如下

  1. 先判断id是否为空
  2. 如果version为null且id为外键
  3. 依据unsavedStrategy判断,尽在返回false时报错,否则存入数据库
  • id == null 则为true
  • id为自定义id且该Generator的allowAssignedIdentifiers方法返回true,则返回null
相关推荐
阿部多瑞 ABU8 小时前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
卷无止境9 小时前
FastAPI 的 WebSocket 装了些什么
后端·python·fastapi
AINative软件工程9 小时前
Agent 上下文账本工程:别让工具结果把 128K 窗口塞成垃圾场
后端·架构·ai编程
卷无止境9 小时前
FastAPI 的 Request 类装了什么
后端·python
程序员爱钓鱼9 小时前
Rust 方法 Method详解:self、方法调用与API设计
后端·面试·rust
橙子家9 小时前
MSDTC(微软分布式事务处理协调器)对系统稳定性的影响
后端
程序员爱钓鱼9 小时前
Go break、continue、goto 详解
后端·面试·go
凤山老林10 小时前
复杂检索引擎落地:Spring Boot + Elasticsearch 数据同步与高阶查询实战
spring boot·后端·elasticsearch
笃行35017 小时前
SQLServer数据迁移之后,那张报表还能不能秒出
后端
LucianaiB18 小时前
别再被 AI 骗了:我把腾讯云 4 个 Skill 做成了个「AI 打假侦探」,过程的一个小配置坑惨了我
后端