能否自定义Hibernate Envers中revinfo表的rev列数据类型?
Hibernate Envers中修改rev列数据类型的方案
一、是否支持修改rev列数据类型?
Hibernate Envers原生不支持将rev列改为UUID等非数值类型,因为@RevisionNumber注解的设计仅限定了int/Integer/long/Long这几种数值类型,核心审计引擎的版本排序、关联追踪等逻辑,都是围绕单调递增的数值版本号构建的。
二、自定义实现非单调版本号的思路
如果一定要用UUID作为版本标识,需要自定义Revision实体和RevisionListener绕过原生限制,步骤如下:
- 自定义Revision实体
创建独立的审计版本实体,替代默认的Revinfo表,注意:- 不用
@RevisionNumber标记UUID字段,将其设为主键并生成UUID - 可选保留
@RevisionTimestamp标记时间戳字段,用于审计时间追踪
示例代码:
@Entity @Table(name = "custom_revinfo") public class CustomRevisionEntity { @Id @GeneratedValue(strategy = GenerationType.UUID) private UUID rev; @Column(name = "revtstmp") private Long revtstmp; // getter、setter方法 } - 不用
- 自定义RevisionListener
实现RevisionListener接口,在生成新版本时手动填充UUID和时间戳:public class CustomRevisionListener implements RevisionListener { @Override public void newRevision(Object revisionEntity) { CustomRevisionEntity revEntity = (CustomRevisionEntity) revisionEntity; revEntity.setRev(UUID.randomUUID()); revEntity.setRevtstmp(System.currentTimeMillis()); } } - 配置Envers使用自定义实体
在配置文件中指定自定义的Revision实体和监听器,以Spring Boot为例:
注意:这种方式会打破Envers原生的版本递增逻辑,依赖版本排序的查询功能需要自行实现,同时所有审计表中的spring.jpa.properties.org.hibernate.envers.revision_entity_name=com.yourpackage.CustomRevisionEntity spring.jpa.properties.org.hibernate.envers.revision_listener=com.yourpackage.CustomRevisionListenerrev外键也要对应改为UUID类型。
三、无需Revinfo表的审计替代方案
如果不想依赖Envers的Revinfo表机制,可选择以下两种方向:
- 手动审计:在业务实体的增删改方法中,手动将历史数据写入自定义审计表,完全控制审计字段(包括用UUID作为标识),但需自行维护关联关系和历史追踪逻辑。
- Spring Data JPA Auditing:该框架支持自定义审计字段,可轻松添加UUID作为审计标识,但它更侧重实体的创建/修改时间、操作者等基础审计,若需要完整历史版本快照,需结合自定义扩展实现。
内容的提问来源于stack exchange,提问作者Partho
相关产品推荐
相关产品推荐

