Search code examples
javagenericscastingjooq

JOOq: update for generalized table


I want to create a generalized method with JOOq that updates a table (specified by a string) using values from a JSON object. I'm not including any validation of tables/fields in this example.

public void updateTable(String table, JsonObject data) {
    Table<?> table = PUBLIC.getTable(table);

    UpdateSetFirstStep<?> update = DSL.using(fooConfig).update(table);

    // Loop through JSON {field1: value1, field2: value2, ...}
    for (Map.Entry<String, Object> entry : data) {
        String fieldName = entry.getKey();
        Field<?> field = table.field(fieldName);

        Object value = entry.getValue();

        // error: no suitable method found for set(Field<CAP#1>,CAP#2)
        update.set(field, field.getType().cast(value));
    }
}

But I get a compile time error: no suitable method found for set(Field<CAP#1>,CAP#2).

I think the problem is that the compiler doesn't know that the type of the field and the type of the value will be the same (hence CAP#1 and CAP#2).

Is there any way to accomplish this?


Solution

  • The simplest solution would be to use the UpdateSetStep.set(Map<? extends Field<?>, ?>) method for this. It applies rather relaxed type safety doing the data type conversion for you (if possible):

    public void updateTable(String table, JsonObject data) {
        Table<?> table = PUBLIC.getTable(table);
    
        DSL.using(fooConfig)
           .update(table)
           .set(data.entrySet()
                    .stream()
                    .map(e -> new SimpleImmutableEntry(table.field(e.getKey()), e.getValue()))
                    .collect(Collectors.toMap(Entry::getKey, Entry::getValue)))
           .where(...) // Don't forget this! ;-)
           .execute();
    }