JOOQ - 如何将 array_agg 与自定义类型字段一起使用
Posted
技术标签:
【中文标题】JOOQ - 如何将 array_agg 与自定义类型字段一起使用【英文标题】:JOOQ - How to use array_agg with custom type field 【发布时间】:2019-10-09 19:43:20 【问题描述】:我正在使用 Jooq(使用 PostgreSQL)。我需要在某些查询中使用array_agg
,以从自定义类型的字段中聚合值。
SELECT TABLE.FIELD1, array_agg(TABLE.FIELD2) FROM TABLE GROUP BY TABLE.FIELD1;
dslContext.select(TABLE.FIELD1, arrayAgg(TABLE.FIELD2))
.from(TABLE)
.groupBy(TABLE.FIELD1)
.fetch();
FIELD2 是 DB 中的 int8
列,通常映射到 Java Long。
我已经定义了一个TypeConverter
forcing 到某个 Java 类的转换。
转换在所有查询中都能正常工作,但在使用 array_agg
时会失败并出现异常:
Caused by: java.sql.SQLException: Error while reading field: array_agg("PUBLIC"."TABLE"."FIELD2"), at JDBC index: 2
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.setValue(CursorImpl.java:1781)
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(CursorImpl.java:1740)
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(CursorImpl.java:1705)
at org.jooq.impl.RecordDelegate.operate(RecordDelegate.java:125)
at org.jooq.impl.CursorImpl$CursorIterator.fetchNext(CursorImpl.java:1669)
... 120 more
Caused by: org.jooq.exception.DataTypeException: Cannot convert from 15 (class java.lang.Long) to class <my custom class>
at org.jooq.tools.Convert$ConvertAll.fail(Convert.java:1167)
at org.jooq.tools.Convert$ConvertAll.from(Convert.java:1056)
at org.jooq.tools.Convert.convert0(Convert.java:322)
at org.jooq.tools.Convert.convert(Convert.java:314)
at org.jooq.tools.Convert.convert(Convert.java:386)
at org.jooq.tools.Convert.convertArray(Convert.java:293)
at org.jooq.tools.Convert$ConvertAll.from(Convert.java:537)
at org.jooq.tools.Convert.convert0(Convert.java:322)
at org.jooq.tools.Convert.convert(Convert.java:314)
at org.jooq.tools.Convert.convert(Convert.java:386)
at org.jooq.impl.DefaultBinding$DefaultArrayBinding.convertArray(DefaultBinding.java:1128)
at org.jooq.impl.DefaultBinding$DefaultArrayBinding.pgGetArray(DefaultBinding.java:1117)
at org.jooq.impl.DefaultBinding$DefaultArrayBinding.get0(DefaultBinding.java:1033)
at org.jooq.impl.DefaultBinding$DefaultArrayBinding.get0(DefaultBinding.java:912)
at org.jooq.impl.DefaultBinding$AbstractBinding.get(DefaultBinding.java:775)
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.setValue(CursorImpl.java:1771)
有什么解决方法吗?这是 JOOQ 的限制吗?
谢谢! 丹
【问题讨论】:
这可能与github.com/jOOQ/jOOQ/issues/7471有关吗? jOOQ 的作者 Lukas Eder 在那里提到该功能应该可以正常工作。也许尝试创建一个完整的、最小的复制示例并在该票中进行提示。另外,您使用的是哪个版本的 jOOQ? 感谢@PetrJaneček 提供问题参考,看来我遇到了同样的问题。我用最新的 JOOQ 版本 (3.11.11) 进行了尝试,并且该问题可以在该版本上重现。 【参考方案1】:我最终得到了以下解决方法:
dslContext.select(TABLE.FIELD1, arrayAgg(TABLE.FIELD2).coerce(Long[].class))
.from(TABLE)
.groupBy(TABLE.FIELD1)
.fetch();
在获取后将 Long 转换为我的自定义类型。
【讨论】:
以上是关于JOOQ - 如何将 array_agg 与自定义类型字段一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何将 DataAnnotations ErrorMessageResourceName 与自定义资源解决方案一起使用