You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中jOOQ Multiset返回嵌套JsonArray无法映射POJO求助

解决Quarkus中jOOQ Multiset配合vertx-jooq的Mutiny流映射问题

问题根源

vertx-jooq 6.5.5的ReactiveMutinyQueryExecutor返回的QueryResult中,Multiset默认被序列化为值数组的嵌套数组(比如[[8,"a","NUMBER"],...]),而非包含JsonObject的数组,直接调用get(TABLE_BS, MyPojo.class)会因类型不匹配抛出转换异常;同时jOOQ的.convertFrom()方法依赖阻塞式fetch()调用,在Mutiny流场景下无法生效。

解决方案

方法1:用jsonObject构造结构化Multiset元素

在Multiset的子查询中,显式用DSL.jsonObject()构造每条记录的JsonObject结构,让Multiset结果直接成为JsonObject数组:

ReactiveMutinyQueryExecutor executor = ...

executor
        .query(dslContext -> dslContext
            .select(TABLE_A.TABLE_C_ID,
                TABLE_C.NAME,
                DSL
                    .multiset(DSL
                        .select(
                            DSL.jsonObject(
                                DSL.key("tableCId").value(TABLE_B.TABLE_C_ID),
                                DSL.key("name").value(TABLE_B.NAME),
                                DSL.key("parameterType").value(TABLE_B.PARAMETER_TYPE)
                            )
                        )
                        .from(TABLE_B)
                        .where(TABLE_B.TABLE_A_ID.eq(TABLE_A.TABLE_A_ID)))
                    .as(TABLE_BS))
            .from(TABLE_A)
            .join(TABLE_C)
            .using(TABLE_C.TABLE_C_ID)
            .where(TABLE_A.TABLE_C_ID.eq(tableCId)))
        .map(queryResult -> {
            // 此时TABLE_BS对应包含JsonObject的JsonArray
            JsonArray tableBsArray = queryResult.get(TABLE_BS, JsonArray.class);
            // 转换为MyPojo列表
            return tableBsArray.stream()
                    .map(jsonObj -> ((JsonObject) jsonObj).mapTo(MyPojo.class))
                    .collect(Collectors.toList());
        });

方法2:用recordInto绑定表记录类型

如果你的MyPojo和jOOQ生成的TableBRecord结构一致,可以用DSL.recordInto()让Multiset返回结构化记录,vertx-jooq会自动将每条记录转为JsonObject:

ReactiveMutinyQueryExecutor executor = ...

executor
        .query(dslContext -> dslContext
            .select(TABLE_A.TABLE_C_ID,
                TABLE_C.NAME,
                DSL
                    .multiset(DSL
                        .selectFrom(TABLE_B)
                        .where(TABLE_B.TABLE_A_ID.eq(TABLE_A.TABLE_A_ID)))
                    .as(TABLE_BS, DSL.recordInto(TableBRecord.class)))
            .from(TABLE_A)
            .join(TABLE_C)
            .using(TABLE_C.TABLE_C_ID)
            .where(TABLE_A.TABLE_C_ID.eq(tableCId)))
        .map(queryResult -> {
            JsonArray tableBsArray = queryResult.get(TABLE_BS, JsonArray.class);
            return tableBsArray.stream()
                    .map(jsonObj -> ((JsonObject) jsonObj).mapTo(MyPojo.class))
                    .collect(Collectors.toList());
        });

关键说明

  • 两种方法都让Multiset的结果从“值数组”变成“JsonObject数组”,避免了类型转换异常。
  • Mutiny流场景下,必须通过JsonArray/JsonObject手动转换为自定义Pojo,不能依赖jOOQ阻塞API的映射方法。

内容的提问来源于stack exchange,提问作者Nikolas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 17:07:57