javamysqljooqjooq-codegen

How to respect DEFAULT values when using JOOQ generated UpdatableRecordImpl from() method


It seems that there had been some work to respect default values when using DAO inserts/updates here: https://github.com/jOOQ/jOOQ/issues/2700.

This is great, however I'm struggling to take advantage of this when also using the generated from method on the UpdatableRecordImpl. Specifically, when generating an UpdatableRecordImpl, we are provided a from method to convert from an entity which implements the record interface to the record, however, if you use this method, DEFAULT fields will not be supported since the from method sets all fields on the entity, including the ones which should be defaulted, and when they are unset, they'll be set to null on the record.

For example, if we have a table fruit, with a single column

alter table fruit
    add column color varchar(6) not null default 'red';

JOOQ would generate an interface IFruit with getters/setters on a field color. Then we would have a FruitRecord class generated which extends UpdatableRecordImpl<FruitRecord> with a from method like the following:

@Override
public void from(IFruit from) {
    setColor(from.getColor());
}

If we make use of this from method, color will be explicitly set to null if it has not been set in the from object. When that happens, when the record is inserted it will fail because color can't be null and won't make use of the default color. If the field was not set at all in the record object, I believe JOOQ would handle that field in a way that it would make use of the DEFAULT value, and therefore insert it properly with the default.

I haven't dug into the complete depths of these generated classes and such, and perhaps I'm missing something, but would there be an existing way to make use of this from method in a way that unset/null fields are distinguished from each other to take advantage of DEFAULT values?

Thanks


Solution

  • Bug

    That's a bug in jOOQ 3.17 and less: #14727. It will be fixed in jOOQ 3.18. It's related to a combination of:

    Workarounds

    The workaround for bug #14727 is to manually upcast the type to Object, to avoid calling the generated method:

    IFruit f = ...
    record.from((Object) f);
    

    Alternatively, you can reset all changed flags on the Record, maybe even globally, using a RecordListener