Подтвердить что ты не робот

Как вставить объект JSON в Postgres с помощью Java readyStatement?

Я пытаюсь вставить объект JSON в свою базу данных postgres v9.4. Я определил столбец "evtjson" как тип json (не jsonb).

Я пытаюсь использовать подготовленный оператор в Java (jdk1.8) для вставки объекта Json (построенного с использованием JEE javax.json) в столбец, но я продолжаю работать с ошибками SQLException.

Я создаю объект JSON, используя:

JsonObject mbrLogRec = Json.createObjectBuilder().build();
…
mbrLogRec = Json.createObjectBuilder()
                .add("New MbrID", newId)
                .build();

Затем я передаю этот объект в качестве параметра другому методу, чтобы записать его в БД, используя подготовленный оператор. (вместе с несколькими другими полями) As:

pStmt.setObject(11, dtlRec);

Используя этот метод, я получаю следующую ошибку:

org.postgresql.util.PSQLException: не установлено расширение hstore.     на org.postgresql.jdbc.PgPreparedStatement.setMap(PgPreparedStatement.java:553)     на org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:1036)

Я также пробовал:

pStmt.setString(11, dtlRec.toString());
pStmt.setObject(11, dtlRec.toString());

Из-за чего возникает другая ошибка:

Событие JSON: { "New MbrID": 29}

SQLException: ОШИБКА: столбец "evtjson" имеет тип json, но выражение имеет характерный символ, изменяющийся

Подсказка: вам нужно будет переписать или применить выражение.

Но, по крайней мере, это говорит мне, что БД распознает столбец как тип JSON. Я попытался установить расширение hstore, но потом сказал мне, что это не объект hstore.

OracleDocs показывает ряд различных методов для установки значения параметра в подготовленном состоянии, но я бы не попробовал их, если кто-то знает ответ. (http://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html) Они также ссылаются на дополнительный параметр SQLType, но я не могу найти ссылки на них.

Должен ли я попробовать setAsciiStream? CharacterStream? CLOB?

4b9b3361

Ответ 1

Такое поведение довольно раздражает, поскольку строки JSON принимаются без проблем при использовании в качестве литералов в командах SQL.

Существует уже issue для этого в репозитории gigub-драйвера postgres (даже если проблема кажется обработкой на сервере).

Кроме того, используя приведение (см. ответ @a_horse_with_no_name) в строке sql автор проблемы предлагает два дополнительных решения:

  • Используйте параметр stringtype=unspecified в URL/опциях подключения JDBC.

Это сообщает PostgreSQL, что все параметры текста или varchar на самом деле неизвестного типа, позволяя ему более свободно выводить свои типы.

  1. Оберните параметр в org.postgresql.util.PGobject:

 PGobject jsonObject = new PGobject();
 jsonObject.setType("json");
 jsonObject.setValue(yourJsonString);
 pstmt.setObject(11, jsonObject);

Ответ 2

Вы можете сделать это так, и вам просто нужна строка json:

Измените запрос на:

String query = "INSERT INTO table (json_field) VALUES (to_json(?::json))"

И установите параметр как строку.

pStmt.setString(1, json);

Ответ 3

Передача JSON в качестве строки - правильный подход, но, как сообщает об этом сообщение об ошибке, вам нужно указать параметр в выражении INSERT в значение JSON:

insert into the_table
   (.., evtjson, ..) 
values 
   (.., cast(? as json), ..)

Затем вы можете использовать pStmt.setString(11, dtlRec.toString()) для передачи значения

Ответ 4

У вас есть два варианта:

  1. Используйте Statement.setString(jsonStr), а затем обработайте преобразование в выражении SQL:

"

PreparedStatement statement = con.prepareStatement("insert into table 
 (jsonColumn) values (?::json)");
 statement.setString(1, jsonStr);

2. Another option is to use PGobject to create a custom value wrapper.

PGobject jsonObject = new PGobject();
 PreparedStatement statement = con.prepareStatement("insert into table 
 (jsonColumn) values (?)");
 jsonObject.setType("json");
 jsonObject.setValue(jsonStr);
 statement.setObject(1, jsonObject);

" Я лично предпочитаю последнее, так как запрос чище

Ответ 5

PostgreSQL чрезмерно, досадно строгий в отношении преобразований типа данных. Он не будет неявно передавать текст даже в текстовые значения, такие как xml и json.

поэтому исходное решение в этом ответе обходит проверку JSON на

создать литье (CHARACTER VARYING как json) без функции как неявное;

здесь CHARACTER VARYING на самом деле вы пытаетесь перейти к вашему подготовленному объекту утверждения.

Ответ 6

Вместо передачи объекта json передать его строковое значение и передать его в json в запросе. Пример:

JSONObject someJsonObject=..........

String yourJsonString = someJsonObject.toString();

String query = "INSERT INTO table (json_field) VALUES (to_json(yourJsonString::json))";

это сработало для меня.

Ответ 7

мне помогло добавить следующую строку в application.properties:

spring.datasource.hikari.data-source-properties.stringtype=unspecified

как писал Wero:

Это говорит PostgreSQL, что все параметры text или varchar на самом деле неизвестного типа