JOOQ:嵌套 MULTISET/ROW/MULTISET/ROW 与临时转换器和 JSON 仿真导致 ClassCastException

问题描述 投票:0回答:1

当执行包含多选子查询的选择时,它本身在多集中执行子查询,我希望结果具有预期的类型。

相反,嵌套结果似乎保留为

ArrayList
并且未正确序列化为目标类型。

重现问题的步骤

record Tuple2(String t1, String t2) {}

var result = db.select(
    multiset(
        select(
            row(
                multiset(
                    select(
                        row("Hello", "World").mapping(Tuple2::new)
                    ).from(dual())
                ).convertFrom(r -> r.map(Record1::component1))
            ).mapping(r -> r)
        ).from(dual())
    ).convertFrom(r -> r.map(Record1::component1))
).from(dual())
.fetchOne(Record1::component1);

log.debug("The result: {}", result);
log.debug("The tuple: {}", result.get(0).get(0));
log.debug("The type of the result: {}", result.get(0).get(0).getClass());

result
的预期类型是
List<List<Tuple2>>
但它似乎是
ArrayList<ArrayList<ArrayList>>
(我猜是行类型的原始表示)。

这段代码的输出是:

The result: [[[[Hello, World]]]]
The tuple: [[Hello, World]]
An unhandled error occurred
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class com.mycompany.mypackage.MyClass$1Tuple2 (java.util.ArrayList is in module java.base of loader 'bootstrap'; com.mycompany.mypackage.MyClass$1Tuple2 is in unnamed module of loader 'app')

jOOQ版本

3.17.8

数据库产品及版本

MySQL 8.0.28

Java 版本

openjdk 版本“19.0.1” 2022-10-18

操作系统版本

无回应

JDBC 驱动程序名称和版本(如果是非官方驱动程序,则包括名称)

mysql:mysql-connector-java:8.0.31

java jooq
1个回答
0
投票

这是 jOOQ 3.18.0、3.17.9 和 3.16.15 中修复的错误:https://github.com/jOOQ/jOOQ/issues/14657

该错误仅影响

JSON
运算符的
MULTISET
仿真,而不影响
XML
仿真,尽管这对于不支持 SQL/XML 的 MySQL 没有帮助。

如错误讨论中所述,可以通过省略其中一个

row()
运算符来解决此特定问题:

var result = db.select(
    multiset(
        select(
            // row( Unnecessary in this case
                multiset(
                    select(
                        row("Hello", "World").mapping(Tuple2::new)
                    ).from(dual())
                ).convertFrom(r -> r.map(Record1::component1))
            // ).mapping(r -> r)
        ).from(dual())
    ).convertFrom(r -> r.map(Record1::component1))
).from(dual())
.fetchOne(Record1::component1);

我意识到这只是一个简化的复制器,实际查询更复杂,尽管这可能有助于解决实际查询中的问题,直到修复可用。

© www.soinside.com 2019 - 2024. All rights reserved.