We use the https://github.com/etiennestuder/gradle-jooq-plugin for generating jOOQ classes on-demand from our database (DDL, .sql file with CREATE TABLE statements). However, we noted that when overriding the strategy.name in jooq.configurations.main.generationTool.generator, we started seeing peculiar behavior.
The database schema
We have some field names like _is_tombstone, _revision etc in our tables. These are for "metadata" which differs from the normal "data" columns (data coming from another system vs "metadata" logging event details about why the change was triggered).
Other tables like id, name etc do not have any special prefix.
The generator
Here is our current generator strategy, inspired by https://www.jooq.org/doc/latest/manual/code-generation/codegen-generatorstrategy/
public class CustomNameGeneratorStrategy extends DefaultGeneratorStrategy {
@Override
public String getJavaMemberName( Definition definition, Mode mode ) {
String memberName = super.getJavaMemberName( definition, mode );
// Converts e.g. _IsTombstone to _isTombstone
if ( memberName.startsWith( "_" ) ) {
memberName = "" + memberName.charAt( 0 ) + toLowerCase( memberName.charAt( 1 ) ) + memberName.substring( 2 );
}
return memberName;
}
@Override
public String getJavaGetterName( Definition definition, Mode mode ) {
String methodName = super.getJavaGetterName( definition, mode );
methodName = methodName.replace( "_", "" );
// isTombstone() seems more natural than getIsTombstone()
methodName = methodName.replace( "getIs", "is" );
return methodName;
}
@Override
public String getJavaSetterName( Definition definition, Mode mode ) {
String methodName = super.getJavaSetterName( definition, mode );
return methodName.replace( "_", "" );
}
}
The problem
With the above in place, the code below causes some very nasty bugs with certain fields not copied from the POJO to the Record instance. Only id, name etc works. All fields which have underscores in the name get excluded in the copying; they have null values in the target Record instance.
This, in turns, makes the DB insertion fail since certain mandatory fields do not have any values.
import static some.package.Tables.GROUPS;
import some.package.tables.records.GroupRecord;
import some.package.tables.pojos.TSDBGroup;
// ...
TSDBGroup tsdbGroup = createTsdbGroup(...);
// The GroupRecord here becomes a "partial copy".
GroupRecord groupRecord = create.newRecord(GROUPS, tsdbGroup);
groupRecord.store();
Why does this happen?