I'm using jOOQ with plain SQL (not generated code). I'm trying to select directly into a POJO that has some fields of type enum.
MyType pojo = context.select().from(table("Table"))
.where(field("ID").equal("1")).fetchOne()
.into(MyType.class);
It seems to me that I can only specify a high-level mapper for my whole POJO, like so:
MyType pojo = context.select().from(table("Table"))
.where(field("ID").equal("1")).fetchOne()
.map(new RecordMapper<Record, MyType>() {
@Override
public MyType map(Record record) {
...
}
});
I can't find a way to only provide mappings or converters for some of the fields. Specifically, I would like to tell jooq something like "convert all fields normally, except if the field in my POJO is of type MyEnum, in which case use this mapping (or converter)".
How can I specify mappers for some fields and not others?
BTW, I noticed I can do something similar at the configuration level, matching database field names with wildcards (as described here), but I think it would be better if the decision would be driven by the type of the fields in the POJO.
There are different ways to tackle this problem:
Obviously. I know you're not using it, but maybe someone who finds this question will be. In that case, the code generator will either:
<forcedTypes/>
, where you can implement your own converters and/or bindings
Even if you're not using the code generator, you can profit from custom converters / bindings by specifying your own DataType
:
// Assuming that the enum type enumerates varchar values:
SQLDataType<MyEnum> myEnumType =
SQLDataType.VARCHAR.asConvertedDataType(new MyEnumConverter());
Now, you can use that type in plain SQL Field
expressions, using DSL.field(String, DataType)
context.select(field("Column", myEnumType), ...)
.from(table("Table"))
In this case, there will be no need for explicit conversion anymore in your record mapper, as the jOOQ Record
will already contain the desired data type.
RecordMapperProvider
If you're using any of the into(Class)
methods, by default, the DefaultRecordMapper
is used. It knows how to convert strings to enums by calling EnumClass.valueOf(stringValue)
. If that's not the desired behaviour (as your question suggests), then you can still override the default behaviour by providing your own RecordMapperProvider
.
This is also a "high level mapper" as you called it, but you can register it globally and reuse it any time you want to map into MyType.class
.
A future version of jOOQ (not jOOQ 3.9 yet) may support a converter registry that allows for implementing default conversions for any pair of types <T, U>
. This is issue #5713.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With