Spring Boot升级后Hibernate Envers审计表列类型验证异常
你遇到的是Hibernate Envers 5.4.11/12版本的潜在回归问题——当实体字段用columnDefinition = "BINARY(60)"标记为String类型时,Envers生成的审计表字段没有正确继承该列定义,结合你的ValidityAuditStrategy+global_with_modified_flag: true配置,最终触发了Schema验证失败。
下面是几个可行的解决方案:
方案一:通过@AuditOverride强制指定审计字段列定义
直接在User实体类上添加@AuditOverrides注解,覆盖Envers的默认映射逻辑,确保审计表字段类型和原表一致:
@Entity @Audited @Inheritance(strategy = InheritanceType.JOINED) @NoArgsConstructor @Getter @Table(name = "users") @AuditOverrides({ @AuditOverride( name = "password", column = @Column(columnDefinition = "BINARY(60)") ) }) public abstract class User extends HasId implements UserDetails { @Column(columnDefinition = "BINARY(60)", nullable = false) private String password; }
这个方法会明确告诉Envers,审计表中的password列要使用BINARY(60)类型,绕过自动映射的bug。
方案二:临时修正数据库表结构(快速应急)
如果不想修改代码,可以手动执行DDL调整审计表列类型:
ALTER TABLE users_aud MODIFY COLUMN password BINARY(60);
执行后重启应用,Schema验证即可通过。但这只是临时方案,后续若重新生成审计表(比如清空数据库),问题会再次出现,建议优先采用方案一。
方案三:降级回Hibernate 5.4.10.Final(兜底方案)
如果上述方案都无效,可以暂时将Hibernate及Envers版本降级回5.4.10.Final,恢复到升级前的稳定状态。同时可以考虑在Hibernate官方Issue Tracker提交该问题,帮助团队定位修复这个未在版本说明中记录的回归bug。
问题原因分析
升级前版本中,Envers能正确继承实体字段的columnDefinition配置,但5.4.11/12版本中,结合ValidityAuditStrategy和修改标记的配置,自动映射逻辑出现偏差,将String类型默认映射为VARCHAR,而非原定义的BINARY,最终导致类型不匹配。
内容的提问来源于stack exchange,提问作者times29

