Spring Boot 4 + Hibernate 7:无法将JsonNode持久化到PostgreSQL的 jsonb字段(InvalidDefinitionException)
我正在尝试将一个 JsonNode 字段持久化到PostgreSQL的 jsonb 列中,使用Spring Boot 4(Hibernate 7)。
实体
import tools.jackson.databind.JsonNode;
import jakarta.persistence.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
@Entity
@Table(name = "my_entity")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
private JsonNode data;
// getters/setters
}
数据库
CREATE TABLE my_entity (
id BIGSERIAL PRIMARY KEY,
data jsonb
);
错误
保存实体时,我得到:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `tools.jackson.databind.JsonNode` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
问题
- 为什么Jackson会尝试将数据反序列化为
com.fasterxml.jackson.databind.JsonNode,而不是tools.jackson.databind.JsonNode? - 是否需要在Hibernate 7中进行额外配置,以正确支持
JsonNode? - 我应该改用不同的类型(例如
String \ byte[])吗?
解决方案
快速修复:
pom.xml
<!-- CHANGE spring-boot-starter-webmvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
<exclusions>
<exclusion>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ADD com.fasterxml.jackson.core jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
MyEntity.java
//CHANGE com.fasterxml.jackson
import com.fasterxml.jackson.databind.JsonNode;
...
public class MyEntity {
简而言之,Spring Boot 4目前混用Jackson 2和 Jackson 3,但使用Jackson 3会带来问题。因此,最快的解决方案是完全切换到Jackson 2。
测试:Spring Boot 4使用Jackson 2和 Jackson 3的混合。
你可以在PostgreSQL中使用INSERT手动创建一个JSON记录。
然后,继续使用Jackson 3(tools.jackson.databind.JsonNode)。然后,通过控制器读取一条记录。它可以成功从JPA仓库检索到一个实体,但其内容不正确,因为它是通过Jackson 3的反序列化读取的。
Spring Boot 4 - 默认:
- Spring MVC使用Jackson 3
- Hibernate使用Jackson 2
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。