jOOQ - 如何使用Postgres表中的数组更新jsonb列以避免SQLDialectNotSupportedException

时间:2017-10-16 16:26:16

标签: java json postgresql jooq

我有一个带有jsonb列的PostgreSQL表,其中包含一个字符串数组,这些字符串是标记值,如下所示:["tag1", "tag2", "tag3"]。我有一个自定义绑定,可以将JSON转换为jackson JsonNode和从jackson JsonNode转换。

自定义绑定在此处定义:https://gist.github.com/HelgeG/0c0b14228f75e91b7542bd6979a05b49

使用基本查找读取记录,然后按如下方式提取JSON列:

VRelease release = releaseModel.find(id);
JsonNode tagNode = release.getTags();

节点转换为List<String>

  List<String> tagList = objectMapper.readValue(
      tagNode.toString(),
      objectMapper.getTypeFactory().constructCollectionType(
          List.class, String.class));

然后我在列表中添加一个字符串,并将列表转换回JSON格式的字符串

  tagList.add(tag);
  String jsonString = objectMapper.writeValueAsString(tagList);

然后我将JSON格式的字符串转换为JsonNode,并尝试将其写回数据库:

  releaseModel.writeTags(id, objectMapper.readValue(jsonString, JsonNode.class));

writeTags方法只执行以下操作:

  public int writeTags(Integer id, JsonNode tagList) {
    return ctx.update(TABLE).set(field(TAG_FIELD_NAME), tagList).where(PRIMARY_KEY.eq(id))
        .execute();
  }

但是,在执行此查询时,我收到以下异常:

org.jooq.exception.SQLDialectNotSupportedException: Type class com.fasterxml.jackson.databind.node.ArrayNode is not supported in dialect POSTGRES

检查调试器中的JsonNode对象,它具有值:

JsonNode in debugger

我一直在努力解决这个问题已经有一段时间了,并且非常感谢jOOQers提供的关于我如何成功地将JSON数组成功写入数据库的经验。

这是jOOQ v3.9.5和PostgreSQL 9.6.5。

1 个答案:

答案 0 :(得分:1)

我假设TAG_FIELD_NAME只是一个描述您的列名的简单String。在这种情况下,解释非常简单。 jOOQ对Binding类型的自定义JsonNode一无所知,更不用说List<ArrayNode>了。

您的代码会进行编译,因为您使用的DSL.field(String)会返回Field<Object>。但是这样的字段只能用于jOOQ和JDBC驱动程序知道如何处理的“普通”JDBC类型。为了实际绑定绑定到您的字段的数据类型,您必须将它提供给jOOQ。写下这个:

DataType<List<ArrayNode>> ARRAY_NODE_LIST = SQLDataType.OTHER.asConvertedDataType(
    new ArrayNodeListBinding());

然后按如下方式使用:

ctx.update(TABLE)
   .set(field(TAG_FIELD_NAME, ARRAY_NODE_LIST), tagList)
   // your new data type here ^^^^^^^^^^^^^^^
   .where(PRIMARY_KEY.eq(id))
   .execute();

现在你只需要编写那个绑定。您发布的绑定在此处不起作用,因为它绑定了JsonNode,而不是List<ArrayNode>