SpringBoot CrudRepository操作MySQL JSON列插入报错求助
解决SpringBoot向MySQL JSON列插入数据的报错问题
我来帮你排查这个问题,你遇到的错误根源其实很简单——你的原生SQL查询里多了不必要的单引号!
错误原因分析
你写的自定义查询是:
@Modifying @Transactional @Query(value = "insert into cs_test_json(config) values (':data')", nativeQuery = true) public void setData(@Param("data") String string);
这里的':data'把参数用单引号包裹后,MySQL会把传入的JSON字符串当成一个带外层单引号的普通字符串,比如实际插入的内容是:
"{"name":"kc","age":28,"city":"Abad"}"
而MySQL的JSON列要求值是纯JSON格式,不能带外层的单引号,这就直接触发了Invalid JSON text的错误。
解决方案1:修改原生SQL查询
只需要去掉参数周围的单引号,Spring Data JPA会自动帮你处理参数的正确传递:
@Modifying @Transactional @Query(value = "insert into cs_test_json(config) values (:data)", nativeQuery = true) public void setData(@Param("data") String string);
这样你的data.toString()生成的合法JSON字符串会被直接传入MySQL,JSON列就能正确识别它了。
解决方案2:更优雅的实体类映射方式(推荐)
手写原生SQL容易出这类细节错误,更规范的做法是用实体类直接映射JSON列,完全避免自定义SQL:
- 创建实体类
import jakarta.persistence.*; @Entity @Table(name = "cs_test_json") public class CsTestJson { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; // 明确指定列类型为JSON @Column(columnDefinition = "JSON") private String config; // 构造函数、Getter、Setter public CsTestJson() {} public CsTestJson(String config) { this.config = config; } // 省略Getter和Setter方法 }
- 简化Repository接口
不需要自定义查询,直接继承CrudRepository即可:
public interface CsTestJsonRepository extends CrudRepository<CsTestJson, Integer> { }
- Controller层代码调整
直接调用save方法插入数据:
JSONObject data = new JSONObject(); data.put("name", "kc"); data.put("age", 28); data.put("city", "Abad"); repository.save(new CsTestJson(data.toString()));
如果想更类型安全,还可以用Jackson的JsonNode直接映射JSON列:
- 实体类中修改字段类型:
import com.fasterxml.jackson.databind.JsonNode; // ... @Column(columnDefinition = "JSON") private JsonNode config;
- Controller层代码:
ObjectMapper mapper = new ObjectMapper(); JsonNode data = mapper.createObjectNode() .put("name", "kc") .put("age", 28) .put("city", "Abad"); repository.save(new CsTestJson(data));
Spring Data JPA会自动处理JsonNode与MySQL JSON列的转换,无需手动转字符串。
内容的提问来源于stack exchange,提问作者Kanhaiya Choudhary
相关产品推荐
相关产品推荐

