Hibernate 7中获取自动生成ID的方法及非提交事务场景咨询
Hibernate 7中获取自动生成ID的方法及非提交事务场景咨询
嗨,刚好碰到过类似的问题,我来给你捋清楚怎么解决!
首先得明白为啥Hibernate 7里用session.persist()之后拿不到ID:和之前的save()不同,persist()设计上就是延迟执行SQL操作的,默认不会立刻触发数据库的insert,所以ID自然不会被填充到你的实体对象里。但你用的是IDENTITY生成策略,这种策略的ID是数据库端自动生成的,必须执行insert语句才能拿到——这时候不用提交事务,只需要手动触发会话同步就行。
给你两种实用的解决方案:
方法一:手动调用session.flush()
这是最直接的方式,调用persist()之后,手动执行flush操作,Hibernate会把当前会话中的持久化操作同步到数据库(执行insert语句),但不会提交事务,这时候实体对象的id字段就会被自动填充了。代码示例如下:
// 1. 创建你的实体实例并设置其他属性 YourEntity yourEntity = new YourEntity(); yourEntity.setName("测试实体"); // ... 其他属性赋值 // 2. 持久化对象 session.persist(yourEntity); // 3. 手动触发flush,同步到数据库(执行insert) session.flush(); // 4. 现在就能拿到自动生成的ID了! int generatedId = yourEntity.getId();
方法二:使用session.saveOrUpdate()(可选)
如果你还是怀念之前save()的行为,Hibernate 7里其实还保留了session.saveOrUpdate()方法,它的行为和旧版的save()类似,执行后会立即触发SQL操作并把ID填充到实体对象里,同样不需要提前提交事务。不过官方更推荐用persist()配合flush,所以这个算是备选方案:
YourEntity yourEntity = new YourEntity(); yourEntity.setName("测试实体"); // 调用saveOrUpdate,直接获取ID int generatedId = (Integer) session.saveOrUpdate(yourEntity); // 或者也可以从实体对象里拿 // int generatedId = yourEntity.getId();
最后提醒一下:不管用哪种方法,flush之后事务还是处于未提交状态,如果后续执行session.rollback(),数据库里的这条记录会被回滚,但你内存里的实体对象ID还是存在的——这个值只是数据库生成过的ID,并不是有效持久化的记录ID哦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

