You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate 6自定义ID生成器:使用已有ID或回退至自增

Hibernate 6 兼容的自定义ID生成器实现

需求背景

升级至Java 21和Spring Boot 3.5.x(引入Hibernate 6)后,原有自定义ID生成器无法正常工作,需要重写以满足以下要求:

  • 若实体已设置ID,直接使用该ID
  • 若ID为null,则由数据库的AUTO_INCREMENT(IDENTITY)机制自动生成

原有Hibernate旧版本实现

public class UseExistingOrGenerateIdGenerator extends IdentityGenerator 
                                               implements IdentifierGenerator {
    @Override
    public Serializable generate(SharedSessionContractImplementor session, 
                                 Object object) throws HibernateException {
        Serializable id = session.getEntityPersister(null, object)
                .getClassMetadata().getIdentifier(object, session);
        return id != null ? id : super.generate(session, object);
    }
}

Hibernate 6 等效实现

Hibernate 6中ClassMetadata已被废弃,需改用EntityPersister的新API来获取实体ID,同时确保回退逻辑直接委托数据库的自增机制,而非Hibernate管理的序列。以下是兼容实现:

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.persister.entity.EntityPersister;

public class UseExistingOrGenerateIdGenerator extends IdentityGenerator implements IdentifierGenerator {

    @Override
    public Object generate(SharedSessionContractImplementor session, Object entity) {
        // 获取当前实体的EntityPersister
        EntityPersister persister = session.getEntityPersister(null, entity);
        // 获取实体当前的ID值
        Object id = persister.getIdentifier(entity, session);
        
        // 如果ID不为null,直接返回;否则调用父类逻辑(触发数据库AUTO_INCREMENT)
        return id != null ? id : super.generate(session, entity);
    }
}

关键说明

  • 获取实体ID:通过EntityPersister.getIdentifier(entity, session)替代旧版的ClassMetadataAPI,这是Hibernate 6推荐的方式
  • 回退逻辑:父类IdentityGenerator的generate方法会直接触发数据库的IDENTITY/AUTO_INCREMENT机制,确保每个表使用自身的自增序列,不会出现跨表ID延续的问题

为什么不能使用SequenceStyleGenerator

现有业务表的ID不连续,各表最大ID差异较大:

users table:       max id 300
products table:    max id 50000
orders table:      max id 120000

若使用SequenceStyleGenerator的共享序列,所有新插入的记录会从最大的ID值(120000+)开始,不符合业务要求。而上述实现依赖数据库原生的AUTO_INCREMENT,每个表会从自身的最大ID自然延续自增。

内容的提问来源于stack exchange,提问作者visal vishmitha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.09 02:12:31