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

使用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的类型转换错误。

解决步骤

  1. 修正审计表字段类型
    执行SQL将message_body字段类型改为jsonb:

    ALTER TABLE shared.fm_sqs_message_aud 
    ALTER COLUMN message_body TYPE jsonb USING message_body::jsonb;
    
  2. 确保Envers正确识别字段类型

    • 确认项目已引入hibernate-types依赖(对应版本,如com.vladmihalcea:hibernate-types-52),保证JsonBinaryType能被Hibernate正确加载
    • 若使用自动建表机制,可通过配置强制Envers继承原表的字段类型,或改为手动维护审计表结构,确保与原表字段类型完全匹配
  3. 清理无效数据(若存在)
    如果审计表中已有message_body字段的无效值,需先清理或转换这些数据,再执行字段类型修改操作。

内容的提问来源于stack exchange,提问作者Danny Petrunov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:25:32