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

如何解决JOOQ Converter转换PostgreSQL数组到Scala List[Long]的类型异常?

解决JOOQ中PostgreSQL Integer数组到Scala List[Long]的映射问题

问题根源

你遇到的ClassCastException是因为JDBC从PostgreSQL读取integer[]类型时,返回的是**Array[Integer](包装类型对象数组)**,而非你尝试强转的Array[Int](原始类型数组)——这两种数组在JVM中是完全独立的类型,无法直接强制转换。

正确的转换器实现

针对List[Long]的转换器需要逐个处理包装类型数组的元素,而非直接强转数组本身:

import org.jooq.Converter
import java.lang.{Integer => JInteger}

class JooqLongArrayConverter extends Converter[Array[Object], List[Long]] {
  override def from(databaseObject: Array[Object]): List[Long] =
    Option(databaseObject)
      .map(_.map {
        case i: JInteger => i.toLong
        case _ => 0L // 可选:添加非预期类型的默认值处理逻辑
      }.toList)
      .getOrElse(List.empty)

  override def to(userValue: List[Long]): Array[Object] =
    userValue.map(_.toInt.asInstanceOf[Object]).toArray

  override def fromType(): Class[Array[Object]] = classOf[Array[Object]]
  override def toType(): Class[List[Long]] = classOf[List[Long]]
}

转换器使用方式

和字符串数组转换器的用法一致,先创建对应的JOOQ DataType:

private val jooqLongArrayConverter = org.jooq.impl.SQLDataType.INTEGER.getArrayDataType.asConvertedDataType(
  new JooqLongArrayConverter()
)

然后替换查询中对应的字段定义:

JooqBuilder
  .default(conn)
  .select(
    field("id", classOf[String]),
    field("dimensions", jooqStringArrayConverter),
    field("dimensionCodes", jooqLongArrayConverter)
  )
  .from(table(MY_TABLE))
  .fetchInto(classOf[MyRecord])
  .asScala
  .toList

补充说明

  • to方法中将Long转为Int,是因为PostgreSQL的integer[]存储的是32位整数,需确保业务场景中Long值不会超出Int的范围;若需要存储更大数值,建议将数据库字段改为bigint[],并把转换器中的Integer替换为Long,同时使用SQLDataType.BIGINT.getArrayDataType。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 04:05:56