PostgreSQL中Hibernate Envers与UUID类型兼容问题求助
解决方案:PostgreSQL下Hibernate-Envers UUID与VARCHAR类型不匹配问题
问题根源
PostgreSQL对类型匹配的校验比H2严格,当实体ID是UUID类型但数据库字段为VARCHAR(36)时,Hibernate-Envers生成的查询会直接以UUID类型参数匹配VARCHAR字段,导致数据库抛出类型不兼容错误。H2会自动隐式转换,因此无此问题。
可行解决方案
1. 调整实体ID的映射注解(推荐)
将@JdbcTypeCode(SqlTypes.CHAR)替换为@Type(type = "uuid-char"),明确指定UUID以字符串形式映射到数据库的VARCHAR字段:
@Entity @Audited @Table(name="MY_RULE") public class MyRule { @Id @Column(name="ID") @Type(type = "uuid-char") private UUID id; @Column(name="RULE_NAME") private String ruleName; // getters & setters }
该配置会让Hibernate(包括Envers)在交互时自动将UUID转换成字符串,与数据库的VARCHAR字段匹配。
2. 全局配置Hibernate UUID映射策略
如果不想修改实体代码,可以在Spring Boot配置文件中添加全局参数,强制Hibernate将UUID默认映射为VARCHAR类型:
# application.properties spring.jpa.properties.hibernate.type.preferred_uuid_jdbc_type=VARCHAR
针对Hibernate 6+版本,使用以下配置:
spring.jpa.properties.hibernate.type.uuid.default_sql_type=VARCHAR
该配置作用于所有UUID类型的字段,Envers生成的查询也会遵循此规则。
3. 自定义修订查询方法
如果前两种方案无法生效,可自定义RevisionRepository方法,手动处理UUID到字符串的转换:
@Repository public interface MyRuleRevisionRepository extends RevisionRepository<MyRule, UUID, Integer> { @Query("SELECT rev FROM Revision rev WHERE rev.entityId = CAST(:id AS string) ORDER BY rev.revisionNumber DESC LIMIT 1") Optional<Revision<Integer, MyRule>> findLastChangeRevision(@Param("id") UUID id); }
使用这个自定义方法替代Spring Data默认的findLastChangeRevision,显式将UUID参数转换为字符串后再查询。
内容的提问来源于stack exchange,提问作者Vytautas Arminas
相关产品推荐
相关产品推荐

