英文:
Nesting MULTISET/ROW/MULTISET/ROW with ad-hoc converters and JSON emulation results in ClassCastException
问题
代码示例中描述了一个问题,涉及到多层嵌套的子查询,但结果的类型与预期不符。期望的结果类型是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。JDBC 驱动程序是 mysql:mysql-connector-java:8.0.31。
英文:
When performing a select which includes a subquery in multiselect, which itself performs a subquery in a multiset, I would expect the result to have the expected type.
Instead, the nested result appears to be left as an ArrayList
and not serialized properly to the target type.
Steps to reproduce the problem
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());
The expected type of result
is List<List<Tuple2>>
but instead it appears to be ArrayList<ArrayList<ArrayList>>
(I'm guessing the raw representation of the row type).
The output of this code is:
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 Version
3.17.8
Database product and version
MySQL 8.0.28
Java Version
openjdk version "19.0.1" 2022-10-18
OS Version
No response
JDBC driver name and version (include name if unofficial driver)
mysql:mysql-connector-java:8.0.31
答案1
得分: 2
这是一个在 jOOQ 3.18.0、3.17.9 和 3.16.15 中修复的错误: https://github.com/jOOQ/jOOQ/issues/14657
这个错误只影响了 MULTISET
运算符的 JSON
模拟,而不影响 XML
模拟,尽管这对于不支持 SQL/XML 的 MySQL 来说并没有帮助。
正如在错误讨论中所指出的,这个特定问题可以通过省略其中一个 row()
运算符来解决:
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);
我明白这只是一个简化的复制示例,实际查询更加复杂,不过也许这可以帮助在实际查询中解决问题,直到修复可用为止。
英文:
This is a bug that was fixed in jOOQ 3.18.0, 3.17.9, and 3.16.15: https://github.com/jOOQ/jOOQ/issues/14657
The bug only affected JSON
emulations of the MULTISET
operator, not XML
emulations, though that doesn't help as a workaround for MySQL, which doesn't support SQL/XML.
As noted in the bug discussion, this particular problem can be worked around by omitting one of the row()
operators:
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);
I realise that this is just a simplified reproducer, the real query being more complex, though perhaps this helps work around the problem also in the real query, until the fix is available.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论