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

JOOQ Multiset查询结合自定义类型时触发DataTypeException的问题及解决方法寻求

JOOQ Multiset查询结合自定义类型时触发DataTypeException的问题及解决方法寻求

最近在项目里用jOOQ做查询时碰到了一个挺头疼的问题,想跟大家聊聊细节,也求个可行的临时 workaround。

问题背景

我们项目用的是PostgreSQL,定义了一个自定义复合类型:

CREATE TYPE attached_file AS (
  id int8,
  file_name varchar(255),
  file_size int8,
  bucket bucket_type
);

查询里用到了multiset()调用,内部包含了涉及这个自定义类型的复杂表达式。偶尔会触发DataTypeException,错误信息大概是:

1234 (BigDecimal) cannot be converted to Bucket.class

看报错栈是在org.jooq.impl.JSONReader的312行,对应代码逻辑是:

if (value instanceof List) 
  l = patchRecord(ctx, multiset, actualRow, (List<Object>) value); 
else if (value instanceof Map) 
  l = patchRecord(ctx, multiset, actualRow, new ArrayList<>(((Map<?, ?>) value).values())); 
else 
  throw new IllegalStateException();

调试发现的根因

我debug了一下,发现问题出在actualRow参数和value的字段顺序不匹配:

  • value是个LinkedHashMap,但它的键值对顺序和actualRow里预期的字段顺序完全不一致
  • patchRecord方法直接调用map.values()把值按顺序取出来,返回的Object列表顺序完全错位
  • 结果就出现了把file_size字段的数字值强行转成Bucket枚举的离谱情况,直接触发类型转换异常

看起来这像是jOOQ的一个bug,但很难稳定复现,也没法快速写出精准的测试用例。从代码逻辑看,patchRecord处理Map的时候应该按key匹配字段,而不是直接取values的顺序,但现在没修复的情况下,得先找个临时办法绕开。

已经尝试过但没用的Workaround

我已经试了几个方向,但都没解决问题:

  • 切换到其他multiset模拟模式
  • 替换成multiset_agg
  • 调整查询里row()的写法,比如把原来的:
    row(
      LOAD_BOOKING_INFO.fkBookedBy(),
      LOAD_BOOKING_INFO.fkBookedBy().portalUser(),
      LOAD_BOOKING_INFO.fkBookedBy().disposalFacilityAccessCode(),
      LOAD_BOOKING_INFO.fkBookedBy().disposalFacilityContact(),
      LOAD_BOOKING_INFO.fkBookedBy().companyAccessCode().company()
    ).convertFrom(mapping(AuthLoginDto::new))
    
    改成了:
    row(
      AUTH_LOGIN.asTable(),
      AUTH_LOGIN.portalUser(),
      AUTH_LOGIN.disposalFacilityAccessCode(),
      AUTH_LOGIN.disposalFacilityContact(),
      COMPANY_ACCESS_CODE.company()
    ).convertFrom(mapping(AuthLoginDto::new)).as(BOOKED_BY)
    
    但因为自定义类型字段还是隐含了关联查询,本质上没解决顺序不匹配的问题。

现在急需一个能临时绕开这个问题的办法,有没有朋友碰到过类似情况,或者有什么思路可以试试?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:53:00