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

使用jOOQ的jsonArrayAgg查询MariaDB/MySQL时触发SQL语法错误异常

问题:jOOQ使用jsonArrayAgg时抛出语法错误,但直接执行SQL正常

当SQL语句包含jsonArrayAgg命令时,jOOQ总是抛出异常:“You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near”。但开启MariaDB的general_log后,将jOOQ生成的SQL语句复制到数据库执行却一切正常,结果符合预期。

代码示例

list = ctx.select(
            MAIN.KEYID,
            field(
            select(jsonArrayAgg(
                jsonObject(
                    key("id").value(CONNECTOR.ID),
                    key("standard").value(CONNECTOR.STANDARD)
            ))).from(CONNECTOR)
            .where(CONNECTOR.MAINKEYID.eq(MAIN.KEYID))).as("connectors")                                
        ).from(MAIN)           
        .fetchInto(JSON_POJO.class);

jOOQ报错日志

at org.jooq_3.15.12.MARIADB.debug(Unknown Source) ~[?:?]
    at org.jooq.impl.Tools.translate(Tools.java:2997) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:639) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:354) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:295) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.AbstractResultQuery.fetchLazyNonAutoClosing(AbstractResultQuery.java:316) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.SelectImpl.fetchLazyNonAutoClosing(SelectImpl.java:2866) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.ResultQueryTrait.collect(ResultQueryTrait.java:357) ~[jooq-3.15.12.jar:?]
    at org.jooq.impl.ResultQueryTrait.fetchInto(ResultQueryTrait.java:1423) ~[jooq-3.15.12.jar:?]

jOOQ生成的SQL代码

set @t = @@group_concat_max_len; set @@group_concat_max_len = 4294967295; 
select `mydb`.`main`.`keyid`, 
(select json_merge_preserve('[]', concat('[', group_concat(json_merge_preserve('{}', json_object('id', `mydb`.`Connector`.`id`), json_object('standard', `mydb`.`Connector`.`standard`)) separator ','), ']')) 
from `mydb`.`Connector` where `mydb`.`Connector`.`mainKeyid` = `mydb`.`main`.`keyid`) as `connectors` from `mydb`.`main`; 
set @@group_concat_max_len = @t

已尝试的无效方案

  • jOOQ版本从3.12升级到3.16
  • MariaDB从10.3升级到10.11
  • 使用Java 11.0.18版本
  • 配置连接参数allowMultiQueries = true

解决思路与替代方案

1. 强制使用MariaDB原生JSON聚合函数

MariaDB 10.5+原生支持json_arrayagg,可以绕过jOOQ的模拟实现,直接调用原生函数:

// 在子查询中直接使用原生SQL函数
field("json_arrayagg(json_object('id', {0}, 'standard', {1}))", 
     JSON.class, CONNECTOR.ID, CONNECTOR.STANDARD)

也可以通过jOOQ配置强制启用原生JSON函数支持:

Settings settings = new Settings()
    .withDialect(SQLDialect.MARIADB)
    .withRenderNameStyle(RenderNameStyle.AS_IS);
DSLContext ctx = DSL.using(connection, SQLDialect.MARIADB, settings);

2. 改用Java端聚合

放弃SQL端聚合,通过JOIN查询所有数据后,在Java代码中手动分组聚合:

// 查询关联数据
List<Record> records = ctx.select(MAIN.KEYID, CONNECTOR.ID, CONNECTOR.STANDARD)
    .from(MAIN)
    .leftJoin(CONNECTOR).on(CONNECTOR.MAINKEYID.eq(MAIN.KEYID))
    .fetch();

// Java端分组转换
Map<Long, List<ConnectorDTO>> connectorMap = records.stream()
    .collect(Collectors.groupingBy(
        r -> r.get(MAIN.KEYID),
        Collectors.mapping(
            r -> new ConnectorDTO(r.get(CONNECTOR.ID), r.get(CONNECTOR.STANDARD)),
            Collectors.toList()
        )
    ));

List<JSON_POJO> list = connectorMap.entrySet().stream()
    .map(entry -> new JSON_POJO(entry.getKey(), entry.getValue()))
    .collect(Collectors.toList());

3. 匹配驱动与组件版本

确保MariaDB JDBC驱动版本与jOOQ、MariaDB服务器版本完全兼容,例如使用MariaDB Connector/J 3.0+配合jOOQ 3.16+,可能解决多语句执行的兼容性问题。

内容的提问来源于stack exchange,提问作者deniro.wang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:05:32