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
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:
NOT NULL
columns<interfaces>true</interfaces>
in the code generator (which generates this slightly optimised method)Record.from(Object)
, which violates the Liskov principleThe 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