Ошибка при попытке получить данные json из базы данных h2

У меня есть следующее определение таблицы

create table samples (
   channel text,
   eventType text,
   data json NOT NULL
);

Я также попытался определить столбец data как clob, text, java_object, varchar, other. Я использую следующий API для вставки данных в h2:

def insert(sample: Sample): Unit = DB localTx { implicit session =>
    val propertiesJson = new PGobject()
    propertiesJson.setType("json")
    propertiesJson.setValue(sample.properties.toJson.toString)
    sql"""
         insert into samples
         (channel,eventType,data) values (${sample.channel}, ${sample.eventType},$propertiesJson )
    """.update().apply()

}

и этот для получения данных

  def find(channel: String): List[Sample] = DB readOnly { implicit session =>
    sql"""
     select * from samples where channel = $channel
     """.map(rs => {

     Sample(
       channel = rs.string("channel"),
       properties = rs.string("data").parseJson.convertTo[Map[String, String]],
       eventType = rs.string("eventType")
     )
    }
    ).list().apply()
   }

Я использую неявные преобразования, используя spray и драйвер scalikejdbc.

Существуют разные ошибки, которые я получаю в зависимости от типа данных столбца data.

  • Для CLOB,VARCHAR,TEXT и JAVA_OBJECT: я могу вставить данные в h2, но при попытке получить я получаю

    spray.json.JsonParser$ParsingException: Unexpected character 'a' at input index 0 (line 1, position 1), expected JSON Value: aced00057372001c6f72672e706f737467726573716c2e7574696c2e50476f626a656374f903de2682bdcb3b0200024c0004747970657400124c6a6176612f6c616e672f537472696e673b4c000576616c756571007e000178707400046a736f6e74001f7b2270726f7041223a2276616c41222c2270726f7042223a2276616c42227d
    
  • Для JSON. Я даже не могу вставить данные в h2. я собираюсь

    Caused by: org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "OTHER to JSON" [22018-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:457)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    ... 114 more
    

При использовании JSON я также попробовал эту директиву format json, предложенную здесь

См. также литеральную грамматику json. Сопоставляется с байтом []. Чтобы установить значение JSON с java.lang.String в PreparedStatement, используйте формат данных FORMAT JSON (INSERT INTO TEST(ID, DATA) VALUES (?, ? FORMAT JSON)). Без формата данных значения VARCHAR преобразуются в строковые значения JSON.

но ошибка осталась та же.

Итак, есть идеи? Как я могу успешно вставлять и извлекать данные JSON из базы данных h2? Что-то не так с моим подходом?


person Niko    schedule 27.11.2020    source источник


Ответы (1)


Я не знаком со Scala, но вы определенно не можете использовать PGobject с H2, этот класс специфичен для PgJDBC. Чтобы передать значение JSON в H2, вам нужно использовать простой массив байтов (byte[] в Java, Array[Byte] в Scala); передаваемый массив должен содержать текст JSON в кодировке UTF-8, UTF-16 или UTF-32. Вы также можете использовать java.lang.String, если хотите, но для этого потребуется предложение FORMAT JSON в SQL после параметра.

Чтобы прочитать значение JSON из H2, было бы лучше использовать ResultSet.getBytes(…) в Java/JDBC и WrappedResultSet.bytes(…) в ScalikeJDBC, он вернет массив байтов с текстом JSON в кодировке UTF-8. В настоящее время вы используете метод string(…), он должен работать как минимум с H2 1.4.200, но такое поведение не задокументировано и может быть изменено в будущих версиях.

Эти предложения предназначены для встроенного типа данных JSON H2.

person Evgenij Ryazanov    schedule 28.11.2020