升级SpringBoot与Hibernate后JsonBinaryType实例化失败求助
问题描述
近期将SpringBoot版本升级至3.0.2,同时把Hibernate依赖升级到6.1.6.Final,使用hypersistence util的hypersistence-utils-hibernate-60依赖:
<dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <scope>compile</scope> <version>6.1.6.Final</version> </dependency> <dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-utils-hibernate-60</artifactId> <version>3.2.0</version> </dependency>
升级后,尝试为PostgreSQL的jsonb列创建Bean时出现异常,该列用于存储JSON对象,异常栈如下:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to instantiate AttributeConverter [io.hypersistence.utils.hibernate.type.json.JsonBinaryType] Caused by: java.lang.IllegalStateException: Unable to instantiate AttributeConverter [io.hypersistence.utils.hibernate.type.json.JsonBinaryType] Caused by: org.hibernate.AnnotationException: Unable to create AttributeConverter instance Caused by: org.hibernate.AnnotationException: Could not extract type argument from attribute converter class 'io.hypersistence.utils.hibernate.type.json.JsonBinaryType'
升级前(使用hibernate-type-52)的代码:
@Entity @Table(name = "test_table") @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) public class TestTable implements Serializable { private static final long serialVersionUID = 1L; @Type(type = "jsonb") @Column(name = "payload_data", columnDefinition = "jsonb") private Object payload; }
升级后的代码:
@Entity @Table(name = "test_table") public class TestTable implements Serializable { private static final long serialVersionUID = 1L; @Convert(converter = JsonBinaryType.class) @Column(name = "payload", columnDefinition = "jsonb") private Object payload; }
解决方案
核心问题是混淆了**Hibernate自定义类型(CustomType)和JPA属性转换器(AttributeConverter)**的用法:JsonBinaryType是Hibernate的自定义类型,并非JPA规范中的AttributeConverter实现,因此不能用@Convert注解指定它。
针对Hibernate 6 + hypersistence-utils-hibernate-60的场景,正确用法有两种:
方式一:继续使用Hibernate自定义类型(推荐)
保持类似升级前的写法,适配Hibernate 6的注解规则即可:
@Entity @Table(name = "test_table") // 全局注册类型定义(可选,也可直接在字段上指定typeClass) @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) public class TestTable implements Serializable { private static final long serialVersionUID = 1L; // 方式1:使用全局注册的类型名称 @Type(type = "jsonb") @Column(name = "payload", columnDefinition = "jsonb") private Object payload; // 方式2:直接指定类型类(无需全局@TypeDef) // @Type(typeClass = JsonBinaryType.class) // @Column(name = "payload", columnDefinition = "jsonb") // private Object payload; }
方式二:使用JPA属性转换器
如果偏好JPA规范注解,可使用hypersistence utils提供的专门转换器类JsonBinaryConverter:
@Entity @Table(name = "test_table") public class TestTable implements Serializable { private static final long serialVersionUID = 1L; @Convert(converter = JsonBinaryConverter.class) @Column(name = "payload", columnDefinition = "jsonb") private Object payload; }
额外注意事项
- 你的
hypersistence-utils-hibernate-60版本(3.2.0)与Hibernate 6.1.6.Final版本兼容,无需调整依赖版本; - 若
payload字段有具体类型(如Map<String, Object>或自定义DTO),建议指定泛型类型,可提升序列化/反序列化的严谨性,避免类型转换问题。
内容的提问来源于stack exchange,提问作者srikant_mantha
相关产品推荐
相关产品推荐

