2014-11-20 55 views
8

我跟着Is it possible to write a data type Converter to handle postgres JSON columns? 的答案來實現nodeObject轉換器。如何使用JOOQ在PostgreSQL中插入帶有JSON列的可更新記錄?

然後我試圖使用一個可更新的記錄插入一條記錄,我。「org.jooq.exception.SQLDialectNotSupportedException:Type類org.postgresql.util.PGobject不方言POSTGRES支持」異常」

我怎樣才能解決這個

以下是我的代碼:

TableRecord r = create.newRecord(TABLE); 
ObjectNode node = JsonNodeFactory.instance.objectNode(); 
r.setValue(TABLE.JSON_FIELD, node, new JsonObjectConverter()); 
r.store(); 
+0

在jOOQ 3.5(剛發佈)之前,PostgreSQL的JSON類型很難與jOOQ集成。我們現在改變了這一點。 [有關此用戶組主題的一些初步信息](https://groups.google.com/d/msg/jooq-user/nThHA-yFrMU/MF6BqcyXpLsJ)。我們很快會更新手冊等,我會詳細回答這個問題。可以肯定的是,你使用的是傑克遜,對吧? – 2014-11-21 16:56:14

+0

是的,我正在使用傑克遜。 – ChromeHearts 2014-11-21 21:45:12

回答

8

由於jOOQ 3.5,你可以在這裏是自己的自定義數據類型綁定註冊代碼生成器:

http://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings

不像Converter,一個Binding決定如何你的數據類型正在以內部jOOQ JDBC級別處理,不知道jOOQ你實現。也就是說,你不僅會定義如何類型(T =數據庫類型,U =用戶類型)<T><U>之間進行轉換,但你也可以定義這樣的類型如何:

  • 呈現爲SQL
  • 綁定到用預處理
  • 綁定到的SQLOutput
  • 註冊於CallableStatements中作爲OUT參數
  • 從結果擷取的
  • 從的SQLInput擷取的
  • 從CallableStatements中作爲OUT擷取的參數

一個例子Binding用於與傑克遜使用以產生JsonNode類型在這裏給出:

public class PostgresJSONJacksonJsonNodeBinding 
implements Binding<Object, JsonNode> { 

    @Override 
    public Converter<Object, JsonNode> converter() { 
     return new PostgresJSONJacksonJsonNodeConverter(); 
    } 

    @Override 
    public void sql(BindingSQLContext<JsonNode> ctx) throws SQLException { 

     // This ::json cast is explicitly needed by PostgreSQL: 
     ctx.render().visit(DSL.val(ctx.convert(converter()).value())).sql("::json"); 
    } 

    @Override 
    public void register(BindingRegisterContext<JsonNode> ctx) throws SQLException { 
     ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR); 
    } 

    @Override 
    public void set(BindingSetStatementContext<JsonNode> ctx) throws SQLException { 
     ctx.statement().setString(
      ctx.index(), 
      Objects.toString(ctx.convert(converter()).value())); 
    } 

    @Override 
    public void get(BindingGetResultSetContext<JsonNode> ctx) throws SQLException { 
     ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index())); 
    } 

    @Override 
    public void get(BindingGetStatementContext<JsonNode> ctx) throws SQLException { 
     ctx.convert(converter()).value(ctx.statement().getString(ctx.index())); 
    } 

    // The below methods aren't needed in PostgreSQL: 

    @Override 
    public void set(BindingSetSQLOutputContext<JsonNode> ctx) throws SQLException { 
     throw new SQLFeatureNotSupportedException(); 
    } 

    @Override 
    public void get(BindingGetSQLInputContext<JsonNode> ctx) throws SQLException { 
     throw new SQLFeatureNotSupportedException(); 
    } 
} 

,這是上面使用可以是Converter看到這裏:

public class PostgresJSONJacksonJsonNodeConverter 
implements Converter<Object, JsonNode> { 
    @Override 
    public JsonNode from(Object t) { 
     try { 
      return t == null 
       ? NullNode.instance 
       : new ObjectMapper().readTree(t + ""); 
     } 
     catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    @Override 
    public Object to(JsonNode u) { 
     try { 
      return u == null || u.equals(NullNode.instance) 
       ? null 
       : new ObjectMapper().writeValueAsString(u); 
     } 
     catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    @Override 
    public Class<Object> fromType() { 
     return Object.class; 
    } 

    @Override 
    public Class<JsonNode> toType() { 
     return JsonNode.class; 
    } 
} 

你現在可以註冊上述bindin g通過代碼生成器配置:

<customType> 
    <name>com.example.PostgresJSONJacksonJsonNodeBinding</name> 
    <type>com.fasterxml.jackson.databind.JsonNode</type> 
    <binding>com.example.PostgresJSONJacksonJsonNodeBinding</binding> 
</customType> 

<forcedType> 
    <name>com.example.PostgresJSONJacksonJsonNodeBinding</name> 
    <expression>my_schema\.table\.json_field</expression> 
</forcedType> 
+0

謝謝盧卡斯!您的解決方案和v3.5即將發佈! – ChromeHearts 2014-12-01 21:39:58

+0

@Lukas,如果我們不知道目標類型,我們想要將任何JSON對象綁定到我們碰巧擁有的任何結果類型對象上?所有轉換器的例子中,type binding都是特定的'DB-Type => User-Type'而不是'DB-Type =>?'(所有postgres對象都是我們現在想要的東西) – 2016-03-09 14:26:39

+0

@JaysonMinard:很難說。恐怕我不完全明白你的問題。也許你可以在Stack Overflow上或者[用戶組](https://groups.google.com/d/forum/jooq-user)上提出一個新問題並附上一些解釋?那麼我很樂意回答。 – 2016-03-09 15:34:16

相關問題