在jooq中使用row()将结果映射到自定义seekStep类
由于我不想使用 RecordX 类(在我的例子中,我从查询返回 11 个字段),因此我创建了自定义映射器来将 SelectSeekStep 结果映射到其中。当我的字段属于连接表的一部分时,就会出现问题。例如,
@Value
public class CustomMapperSelectSeekStep {
private final String field1;
private final String field2;
private final String field3;
private final String field4;
private final String field5;
private final String field6;
private final String field7;
private final String test_id;
private final String field9;
private final String field10;
}
假设除了 test_id
字段之外的所有字段都是主表的一部分(我们称之为 dummy
),并且该字段是 test
表的一部分,其中我们将使用左连接
进行连接。
dslContext
.select(
row(DUMMY.FIELD1,
DUMMY.FIELD2,
DUMMY.FIELD3,
DUMMY.FIELD4,
DUMMY.FIELD5,
DUMMY.FIELD6,
DUMMY.FIELD7,
TEST.TEST_NAME,
DUMMY.FIELD8,
DUMMY.FIELD9,
DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);
我收到异常:
java.lang.IllegalArgumentException: Field ("test"."test_name") is not contained in Row
(row (
"DUMMY"."FIELD1",
"DUMMY"."FIELD2",
"DUMMY"."FIELD3",
"DUMMY"."FIELD4",
"DUMMY"."FIELD5",
"DUMMY"."FIELD6",
"DUMMY"."FIELD7",
"DUMMY"."FIELD8",
"TEST"."TEST_NAME",
"DUMMY"."FIELD9",
"DUMMY"."FIELD10"
))
更新:添加了整个方法调用:
dslContext.transaction(configuration -> {
DSLContext localDsl = DSL.using(configuration);
try (Cursor<Record1<CustomMapperSelectSeekStep>> records =
selectRecords(localDsl)
.fetchSize(1000)
.resultSetType(ResultSet.TYPE_FORWARD_ONLY)
.resultSetConcurrency(ResultSet.CONCUR_READ_ONLY)
.fetchLazy()) {
processRecords(records);
}
});
//method
private SelectSeekStep1<Record1<CustomMapperSelectSeekStep>,Timestamp> selectRecords(DSLContext dslContext) {
return dslContext.select(
row(DUMMY.FIELD1,
DUMMY.FIELD2,
DUMMY.FIELD3,
DUMMY.FIELD4,
DUMMY.FIELD5,
DUMMY.FIELD6,
DUMMY.FIELD7,
TEST.TEST_NAME,
DUMMY.FIELD8,
DUMMY.FIELD9,
DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);
}
在流程记录内,我将 Record
对象映射到所需的对象类型。
void processRecords(List<Records> records) {
record.map(recordMapper);
}
我有自定义 recordMapper 实现,我正在执行如下逻辑:
testName = record.get(TEST.TEST_NAME, Test.class);
堆栈跟踪:
at org.jooq.impl.Tools.indexFail(Tools.java:1769)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:331)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:336)
at org.test.CustomMapper.map(CustomMapper.java:42)
at org.test.CustomMapper.map(CustomMapper.java:16)
at org.jooq.impl.AbstractRecord.map(AbstractRecord.java:904)
at org.test.Processor.processRecords(Processor.java:88)
at org.test.Repository.lambda$fetchLazy$0(Repository.java:78)
at org.jooq.impl.DefaultDSLContext.lambda$transaction$5(DefaultDSLContext.java:611)
at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:549)
Since I don't want to use RecordX class (in my case I am returning 11 fields from query) I've created custom mapper to map SelectSeekStep result into it. The problem occurs when I have fields that are part of joined table. E.g.
@Value
public class CustomMapperSelectSeekStep {
private final String field1;
private final String field2;
private final String field3;
private final String field4;
private final String field5;
private final String field6;
private final String field7;
private final String test_id;
private final String field9;
private final String field10;
}
Let's say that all fields except test_id
fields are part of main table (let's call it dummy
) and that field is part of test
table which we will connect with left join
.
dslContext
.select(
row(DUMMY.FIELD1,
DUMMY.FIELD2,
DUMMY.FIELD3,
DUMMY.FIELD4,
DUMMY.FIELD5,
DUMMY.FIELD6,
DUMMY.FIELD7,
TEST.TEST_NAME,
DUMMY.FIELD8,
DUMMY.FIELD9,
DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);
Exception I am getting:
java.lang.IllegalArgumentException: Field ("test"."test_name") is not contained in Row
(row (
"DUMMY"."FIELD1",
"DUMMY"."FIELD2",
"DUMMY"."FIELD3",
"DUMMY"."FIELD4",
"DUMMY"."FIELD5",
"DUMMY"."FIELD6",
"DUMMY"."FIELD7",
"DUMMY"."FIELD8",
"TEST"."TEST_NAME",
"DUMMY"."FIELD9",
"DUMMY"."FIELD10"
))
UPDATE: added entire method call:
dslContext.transaction(configuration -> {
DSLContext localDsl = DSL.using(configuration);
try (Cursor<Record1<CustomMapperSelectSeekStep>> records =
selectRecords(localDsl)
.fetchSize(1000)
.resultSetType(ResultSet.TYPE_FORWARD_ONLY)
.resultSetConcurrency(ResultSet.CONCUR_READ_ONLY)
.fetchLazy()) {
processRecords(records);
}
});
//method
private SelectSeekStep1<Record1<CustomMapperSelectSeekStep>,Timestamp> selectRecords(DSLContext dslContext) {
return dslContext.select(
row(DUMMY.FIELD1,
DUMMY.FIELD2,
DUMMY.FIELD3,
DUMMY.FIELD4,
DUMMY.FIELD5,
DUMMY.FIELD6,
DUMMY.FIELD7,
TEST.TEST_NAME,
DUMMY.FIELD8,
DUMMY.FIELD9,
DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);
}
Inside process record I am mapping Record
objects to desired object type.
void processRecords(List<Records> records) {
record.map(recordMapper);
}
I have custom recordMapper implementation where i am doing logic like this:
testName = record.get(TEST.TEST_NAME, Test.class);
Stack trace:
at org.jooq.impl.Tools.indexFail(Tools.java:1769)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:331)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:336)
at org.test.CustomMapper.map(CustomMapper.java:42)
at org.test.CustomMapper.map(CustomMapper.java:16)
at org.jooq.impl.AbstractRecord.map(AbstractRecord.java:904)
at org.test.Processor.processRecords(Processor.java:88)
at org.test.Repository.lambda$fetchLazy$0(Repository.java:78)
at org.jooq.impl.DefaultDSLContext.lambda$transaction$5(DefaultDSLContext.java:611)
at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:549)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是您已经将记录嵌套为具有这样的类型
当您认为您有这样的类型时:
在后一种情况下,您可以像您一样简单地提取投影列:
但是当您有一个嵌套记录时,该列不再存在,它嵌套在匿名
Record1
类型中。不仅如此,还因为您使用了 使用convertFrom()
的临时转换器,不再有嵌套记录,但 jOOQ 为您投影了自定义 POJO 类型CustomMapperSelectSeekStep
。因此,只需这样读取您的值:
The problem is that you've nested your record to have a type like this
When you thought you had a type like this:
In the latter case, you could simply extract the projected column like you did:
But when you have a nested record, that column no longer exists, it's nested in an anonymous
Record1<?>
type. Not only that, but because you used an ad-hoc converter usingconvertFrom()
, there's no nested record anymore, but jOOQ projected your custom POJO typeCustomMapperSelectSeekStep
for you.So, just read your value like this: