javajooq

Can no longer set "anonymous" record fields


After updating Java and JOOQ a previously working function seems to run into a type casting error, specifically the lines record.set/with(or any version of setting a column) ...

public void set_col_value(String col, String val, int options) {
        final boolean optional = (options & Optional_Value) != 0;
        if (val == null) {
            if (optional) {
                return;
            }
            throw new RuntimeException("missing value: " + val);
        }
        final boolean as_bool = (options & As_Boolean) != 0;
        if (as_bool) {
            if (val.equals("true")) {
                record.set(table.field(col), true);
            } else if (val.equals("false")) {
                record.with(table.field(col), false);
            } else {
                throw new RuntimeException("bad boolean value: " + val);
            }
        } else {
            record.with(table.field(col), val);
        }
    }

I get this error:

error: no suitable method found for set(Field<CAP#1>,boolean)
record.set(table.field(col), true);
method Record.<T#1>set(Field<T#1>,T#1) is not applicable
(inference variable T#1 has incompatible bounds equality constraints: CAP#2 lower bounds: Boolean)
method Record.<T#2,U>set(Field<T#2>,U,Converter<? extends T#2,? super U>) is not applicable
(cannot infer type-variable(s) T#2,U
(actual and formal argument lists differ in length))
where T#1,T#2,U are type-variables:
T#1 extends Object declared in method <T#1>set(Field<T#1>,T#1)
T#2 extends Object declared in method <T#2,U>set(Field<T#2>,U,Converter<? extends T#2,? super U>)U extends Object declared in method <T#2,U>set(Field<T#2>,U,Converter<? extends T#2,? super U>)
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Object from capture of ?


Solution

  • In order to answer why things used to work and no longer do, I'll need more info (see comments). You probably changed something else as well, including removed some raw type cast, etc.

    But they aren't supposed to work. Look at the Record.set(Field<T>, T) and Fields.field(String) methods. The latter returns Field<?> with a wildcard. You can't just pass Field<?> and boolean to the Record::set method, the T types must match.

    Here's are possible workarounds for that particular call:

    // Using raw types
    record.set((Field) table.field(col), true);
    
    // Using unsafe casts
    record.set((Field<Boolean>) table.field(col), true);
    

    I can't remember a jOOQ version where this wasn't required...