将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的主要内容,如果未能解决你的问题,请参考以下文章