Java Hibernate框架下如何在MySQL数据库中存储JSON类型数据
问题原因分析
- 使用
@Type(type = "json")报错:该注解是Hibernate的扩展自定义类型,默认未内置,缺少对应依赖、实体类未声明类型定义、数据库字段不是JSON类型都会触发报错,严重时会导致数据库连接初始化失败。 - 改为
text类型后字段为空:你传入的field对应值是JSON对象结构,JAX-RS默认的JSON反序列化器(通常为Jackson)无法直接将JSON对象映射为String类型字段,反序列化结果为null,因此存入为空。
解决方案
方案1:使用MySQL JSON类型存储(推荐,支持后续JSON函数查询)
适配Hibernate 5版本
- 引入Hibernate Types扩展依赖(版本对应你的Hibernate核心版本):
<!-- 以Hibernate 5.2+为例 --> <dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>2.21.1</version> </dependency>
- 修正实体类定义:
import com.vladmihalcea.hibernate.type.json.JsonType; import org.hibernate.annotations.TypeDef; @Entity @Table(name = "Field") @TypeDef(name = "json", typeClass = JsonType.class) // 必须加类级注解声明类型 public class Field implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Type(type = "json") @Column(columnDefinition = "json") // 显式指定数据库字段类型 private String field; }
- 确认数据库
Field表的field字段类型为JSON。
适配Hibernate 6版本
Hibernate 6已内置JSON类型支持,无需额外依赖,实体类直接修改为:
@Entity @Table(name = "Field") public class Field implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @JdbcTypeCode(SqlTypes.JSON) private String field; }
方案2:使用TEXT类型存储
如果不需要数据库层面的JSON查询能力,可继续使用TEXT类型,只需添加JSON序列化/反序列化配置即可:
- 自定义JSON对象转字符串反序列化器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class JsonObjectToStringDeserializer extends StdDeserializer<String> { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public JsonObjectToStringDeserializer() { super(String.class); } @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode jsonNode = p.getCodec().readTree(p); return OBJECT_MAPPER.writeValueAsString(jsonNode); } }
- 修正实体类字段注解:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.annotation.JsonRawValue; import org.hibernate.annotations.Type; @Entity @Table(name = "Field") @JsonIgnoreProperties(ignoreUnknown = true) public class Field implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Type(type = "text") @JsonDeserialize(using = JsonObjectToStringDeserializer.class) // 用自定义反序列化器把入参JSON对象转字符串 @JsonRawValue // 序列化返回时直接把字符串当JSON输出,不用转义 private String field; }
请求参数校验
Postman发送请求时需确保整个请求体为合法JSON结构,示例完整请求体:
{ "field": { "value": { "provider": "value", "fields": { "label": "Field File", "type": "file", "required": true } } } }
内容的提问来源于stack exchange,提问作者Mands
相关产品推荐
相关产品推荐

