将json插入postgreSQL

Posted

技术标签:

【中文标题】将json插入postgreSQL【英文标题】:Insert json into postgreSQL 【发布时间】:2019-11-20 02:45:26 【问题描述】:

我正在尝试使用 Java 8、Eclipse 和 SpringBoot 将 ARC 客户端(类似于邮递员)提供的 json 对象插入我的 webService 控制器,然后插入 PostgreSQL 11.4 dB。我收到以下错误:

2019-07-10 13:02:42.356 ERROR 21516 --- [nio-8086-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO cwb_patent(patent_number,created_date,patent_data) VALUES (?,current_timestamp,cast(? AS JSON)) ON CONFLICT (patent_number) DO UPDATE SET patent_data  = cast(? AS JSON), created_date = current_timestamp]; nested exception is org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of com.clarivate.singularity.chemworkbench.webservices.common.PatentChemicalData. Use setObject() with an explicit Types value to specify the type to use.] with root cause
org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of com.clarivate.singularity.chemworkbench.webservices.common.PatentChemicalData. Use setObject() with an explicit Types value to specify the type to use.
at org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:967) ~[postgresql-42.2.2.jar:42.2.2]

我的查询是:

public static final String mergeCwbPatent = "INSERT INTO cwb_patent" + 
        "(patent_number,created_date,patent_data)" +
        " VALUES (:patent_number,current_timestamp,cast(:patent_data AS JSON))" +
        " ON CONFLICT (patent_number)" +
        " DO UPDATE SET patent_data  = cast(:patent_data AS JSON), created_date = current_timestamp";

我的控制器是:

 @RequestMapping(value = "/merge-patent-data", method = RequestMethod.POST)
public Long  mergePatentChemicalData(@RequestBody  PatentChemicalData patentChemicalData)  
    Long ret = db.mergeCwbPatent(patentChemicalData);
    return ret;

而插入的方法是:

public Long mergeCwbPatent(PatentChemicalData pcd)

    Map<String, Object> parameters = new HashMap<String, Object>();

    Long ret = null;
    String patentNumber;

    if (pcd == null )
    
        logger.error("DS4A Trying to Insert invalid PatentChemicalData into CWB_PATENT");
    else 
        patentNumber=pcd.getPatentChemicalData().getPatentNumber();

        logger.debug("DS4B Inserting data for patentNumber = " + patentNumber + " into cwb_patent");
        parameters.put("patent_number", patentNumber);  // THIS LINE THROWS THE ERROR
        parameters.put("patent_data", pcd);   // This is the JSON object

        ret = jdbcTemplate.queryForObject(SqlQueries.mergeCwbPatent, parameters,Long.class);

    

    return ret;

堆栈跟踪显示“使用使用 setObject()”,但这不适用于我的参数 HashMap。 这个tenmilessquare 链接表明我在正确的轨道上,但我似乎无法让它工作。任何帮助表示赞赏。

【问题讨论】:

您需要将您的 JSON 对象转换为字符串,例如使用杰克逊 您似乎正在尝试将 POJO 写入您的数据库,并希望它自动将其转换为 JSON。我不相信它会那样工作。您必须将 POJO 转换为 JSON,然后将其保存到数据库中。 【参考方案1】:

按照@a_horse_with_no_name 的建议,我添加了一个函数来将 PatentChemicalData 对象转换为字符串:

public String patentChemicalDataToJson(PatentChemicalData pcd) throws JsonProcessingException 
     ObjectMapper Obj = new ObjectMapper();
     String jsonStr = Obj.writeValueAsString(pcd);
     return jsonStr;

然后在 mergeCwbPatent() 中我按照建议使用了这个函数:

String jsonPcdStr= sf.patentChemicalDataToJson(pcd);
parameters.put("patent_data", jsonPcdStr);

而且效果很好。 我已经包含了 Jackson,我认为 SpringBoot 会自动进行 Jackson 转换,但事实并非如此。 SpringBoot 的问题在于它让你变得懒惰!

【讨论】:

以上是关于将json插入postgreSQL的主要内容,如果未能解决你的问题,请参考以下文章

如何将json数组插入mysql数据库

如何将json字段插入mysql

如何将字符串数组插入mysql json列

如何将数组值插入现有的 JSON 文档?

将 JSON 文本插入 DB2 表

使用 C# 和 OPENJSON 将 JSON 插入 SQL Server 2016