使用UUID主键时Spring Data Hibernate Envers插入报错排查
问题:Hibernate Envers插入审计记录时出现UUID格式错误
环境版本
- Spring Boot 2.6.6
- Hibernate Core 5.6.7
- Hibernate Envers 5.6.7
- PostgreSQL数据库
实体类代码
@Entity @Getter @Setter @Builder @Audited @ToString @NoArgsConstructor @AllArgsConstructor @Table(name = "fm_sqs_message", schema = "shared") @TypeDefs({ @TypeDef(name = "json", typeClass = JsonStringType.class), @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) }) public class FmSQSMessageEntity { @Id @GeneratedValue @Column(name = "id", updatable = false, nullable = false) private UUID id; @Type(type = "jsonb") @Column(name = "message_body") private String messageBody; }
Envers生成的审计表结构
CREATE TABLE if NOT EXISTS shared.revinfo ( rev int4 NOT NULL, revtstmp int8 NULL, CONSTRAINT revinfo_pkey PRIMARY KEY (rev) ); CREATE TABLE if NOT EXISTS shared.fm_sqs_message_aud ( id uuid NOT NULL, rev int4 NOT NULL, revtype int2 NULL, message_body uuid NULL, message_type varchar(255) NULL, CONSTRAINT fm_sqs_message_aud_pkey PRIMARY KEY (id, rev) ); ALTER TABLE shared.fm_sqs_message_aud DROP CONSTRAINT IF EXISTS fkjh3gcaqcwg2r1g20duafkejf4; ALTER TABLE shared.fm_sqs_message_aud ADD CONSTRAINT fkjh3gcaqcwg2r1g20duafkejf4 FOREIGN KEY (rev) REFERENCES urbanise_mri_integration.revinfo (rev);
异常信息
org.springframework.orm.jpa.JpaSystemException: Unable to perform beforeTransactionCompletion callback: org.hibernate.exception.DataException: could not execute statement; nested exception is org.hibernate.HibernateException: Unable to perform beforeTransactionCompletion callback: org.hibernate.exception.DataException: could not execute statement at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331) ~[spring-orm-5.3.18.jar:5.3.18] ... 省略中间栈信息 **Caused by: org.postgresql.util.PSQLException: ERROR: invalid input syntax for type uuid: "{}"** at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675) ~[postgresql-42.3.3.jar:42.3.3] ... 省略后续栈信息
问题分析与解决方案
核心原因
审计表fm_sqs_message_aud中的message_body字段被错误定义为uuid类型,但实体类中该字段是jsonb类型的字符串。当Envers插入审计记录时,会将原实体的JSON字符串(例如空对象{})尝试写入UUID类型字段,触发PostgreSQL的类型转换错误。
解决步骤
修正审计表字段类型
执行SQL将message_body字段类型改为jsonb:ALTER TABLE shared.fm_sqs_message_aud ALTER COLUMN message_body TYPE jsonb USING message_body::jsonb;确保Envers正确识别字段类型
- 确认项目已引入
hibernate-types依赖(对应版本,如com.vladmihalcea:hibernate-types-52),保证JsonBinaryType能被Hibernate正确加载 - 若使用自动建表机制,可通过配置强制Envers继承原表的字段类型,或改为手动维护审计表结构,确保与原表字段类型完全匹配
- 确认项目已引入
清理无效数据(若存在)
如果审计表中已有message_body字段的无效值,需先清理或转换这些数据,再执行字段类型修改操作。
内容的提问来源于stack exchange,提问作者Danny Petrunov
相关产品推荐
相关产品推荐

