javaspring-bootjooq

How to exclude null values when performing update in JOOQ (REST API PATCH)?


public BankResponse update(BankUpdateRequest request, Integer id) {
  UpdateSetFirstStep<BankRecord> update = dsl.update(BANK);
  UpdateSetMoreStep<BankRecord> moreStep = null;

  if (request.naziv() != null) moreStep = update.set(BANK.NAME, request.naziv());
  if (request.ziroRacun() != null) moreStep = (moreStep != null ? moreStep : update).set(BANK.BANK_ACCOUNT, request.ziroRacun());
  if (request.fax() != null) moreStep = (moreStep != null ? moreStep : update).set(BANK.FAX, request.fax());

  if (moreStep == null) {
     throw new IllegalStateException("No fields to update");
  }

  return moreStep
        .where(BANK.ID.eq(id))
        .returning()
        .fetchOptional()
        .map(r -> r.into(BankResponse.class))
        .orElseThrow(() -> new ResourceNotFoundException(EntityType.BANK, id));
}

Is there a more elegant way to do this in Java JOOQ? The current approach works, but it's going to get increasingly more complex the more fields there are in a given record.


Solution

  • You can use "optional column expressions", which are dummy Field expressions that can be passed to jOOQ's DSL API where they're simply ignored. E.g.:

    public BankResponse update(BankUpdateRequest request, Integer id) {
      return dsl.update(BANK)
         .set(BANK.NAME, request.naziv() != null 
              ? request.naziv() 
              : DSL.noField(BANK.NAME))
         .set(BANK.BANK_ACCOUNT, request.ziroRacun() != null 
              ? request.ziroRacun() 
              : DSL.noField(BANK.BANK_ACCOUNT))
         .set(BANK.FAX, request.fax() != null 
              ? request.fax() 
              : DSL.noField(BANK.NAME))
         .where(BANK.ID.eq(id))
         .returning()
         .fetchOptional()
         .map(r -> r.into(BankResponse.class))
         .orElseThrow(() -> new ResourceNotFoundException(EntityType.BANK, id));
    }