Search code examples
javadatabasemappingrecordjooq

Use Mapstruct as RecordMapper for JOOQ


I would like to implement my own RecordMapper and use Mapstruct to map the Record to the POJO. I don't quite understand how to accomplish this. I followed this part of the docs: https://www.jooq.org/doc/3.13/manual/sql-execution/fetching/pojos-with-recordmapper-provider/

My mapper looks like this:

public class LanguageMapper<R extends Record, E> implements RecordMapper<R, Language> {

  @Override
  public Language map(R record) {
    LanguageRecord languageRecord = (LanguageRecord) record;

    // this is just an example, in the future this is the kind of mapping that would be performed automatically via mapstruct
    return new Language(
             languageRecord.getId(), 
             languageRecord.getNamespaceId(), 
             languageRecord.getLanguage(), 
             languageRecord.getCountryCode(), 
             languageRecord.getLanguageTag()
    );
  }
}

The issue is that as a record I'm not actually getting a LanguageRecord but a RecordImpl of my language table and can thus not cast record to LanguageRecord. Any idea what I need to change?

What's interesting when using the RecordImpl is, if I do something like this

record.get(LANGUAGE.LANGUAGE_TAG);

It will already get the wrong information (it's getting the LANGUAGE.NAMESPACE_ID). Thus when getting it like this and then mapping it to the POJO it will be wrong as well.

(Created this question based on this question POJO Mapping in JOOQ regardless of parameter order)


Solution

  • The question was a result of the problem described here: POJO Mapping in JOOQ regardless of parameter order

    But it turns out that the problem can be solved without even needing any sort of mapper.

    Problem: If JOOQ generates POJOs/Records/etc. based on a database which has the attributes of a table in a certain order, but the order of the attributes changes after JOOQ already generated the POJOs/Records/etc. it's possible that a SELECT * will not map the fields to the correct attributes in the POJOs

    E.g. The POJO Language has the attributes country and language and suddenly Language contains the table value of country in Lanugage.getLanguage() and the table value of lanugage in Language.getCountry().

    This issue can be solved by specifying an order (regardless what the actual order of the database fields are) in the SELECT-statement, like SELECT language, country.