如何用Hibernate IdentifierGenerator为多实体生成不同前缀的自定义ID?
通用动态前缀ID生成器解决方案
1. 实现单一生成器类
创建支持配置前缀的通用ID生成器,通过Hibernate的配置参数动态获取前缀,无需为每个实体单独编写类:
import java.io.Serializable; import java.util.Properties; import java.util.UUID; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.Type; public class PrefixUuidGenerator implements IdentifierGenerator, Configurable { private String prefix; @Override public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws HibernateException { // 从配置中读取前缀参数,可设置默认值(这里默认空字符串) this.prefix = params.getProperty("prefix", ""); } @Override public Serializable generate(SharedSessionContractImplementor session, Object entity) throws HibernateException { String shortUuid = UUID.randomUUID().toString().substring(0, 8); return prefix + shortUuid; } }
2. 实体类中动态配置前缀
每个实体只需在ID注解中指定专属前缀参数,复用同一个生成器类:
Product实体配置示例
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Product { @Id @GeneratedValue(generator = "productIdGenerator") @GenericGenerator( name = "productIdGenerator", strategy = "net.ddns.mrq.util.PrefixUuidGenerator", parameters = { @Parameter(name = "prefix", value = "PROD") } ) @Column(name = "product_id") private String id; private String name; // 其他字段与方法 }
其他实体(如Order)配置示例
@Entity public class Order { @Id @GeneratedValue(generator = "orderIdGenerator") @GenericGenerator( name = "orderIdGenerator", strategy = "net.ddns.mrq.util.PrefixUuidGenerator", parameters = { @Parameter(name = "prefix", value = "ORD") } ) @Column(name = "order_id") private String id; // 其他字段与方法 }
核心逻辑说明
- 实现
Configurable接口的configure方法,用于读取Hibernate配置中的自定义prefix参数。 - 每个实体通过
@GenericGenerator的parameters属性传递不同前缀,生成器自动适配。 - 若无需前缀,可省略
prefix参数或设为空字符串。
该方案完全解决你的需求:仅需一个生成器类,通过动态配置前缀适配所有8个实体,消除代码重复。
内容的提问来源于stack exchange,提问作者Thiago Marquet
相关产品推荐
相关产品推荐

