如何使用jooq(postgresql)处理批量执行中的任何参数化存储函数?

时间:2016-07-19 10:21:32

标签: java postgresql jooq

我有以下数据库模式:

CREATE FUNCTION public.some_fun(anyarray) RETURNS anyarray AS $$
  SELECT $1;
$$ LANGUAGE sql;

CREATE TABLE some_table (some_col int[]);

我在java中调用以下代码:

DSLContext ctx = ... // retrieve DSLcontext
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

代码产生异常:

  

org.postgresql.util.PSQLException:错误:无法确定   多态类型,因为输入的类型为“unknown”

生成的查询是:

  

插入“public”。“some_table”(“some_col”)值   ( “公共的”。 “some_fun”( '{ “1”}'))

事实证明,jooq没有明确地类型转换{1}数组,而postgres无法推断数组类型。

有趣的是,以下代码生成相同的查询并且可以正常工作:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
query.execute();

我想这个问题与jdbc如何处理批量查询有关,除非jooq将不同的查询记录到它真正执行的内容。我使用以下代码找到了解决问题的黑客解决方法:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values(
        (Field) someFun(
            DSL.field(DSL.array(new Integer[]{1}).toString() + "::int[]")
        )
    );
ctx.batch(query).execute();

我还尝试通过将强制转换模式设置为ALWAYS来使jooq始终明确地输入强制转换值,但它似乎不起作用:

ctx.renderContext().castMode(RenderContext.CastMode.ALWAYS);
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

我是否真的需要以手动丑陋的方式进行类型转换,或者有更好的方法来处理它?<​​/ p>

更新

通过生成如下所示的类型转换字符串,可以减少对转换的挫败感:

String.format("::%s[]", DefaultDataType.getDataType(SQLDialect.POSTGRES, Integer[].class).getCastTypeName())

不过,这只是一种解决方法。

1 个答案:

答案 0 :(得分:0)

自jOOQ 3.8起,PostgreSQL的anyanyarray和其他多态数据类型尚不支持。有一个待处理的功能请求: https://github.com/jOOQ/jOOQ/issues/5479

您的解决方法可能与现在一样好。