Available in versions: Dev (3.20) | Latest (3.19) | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11 | 3.10

Qualified converters

Applies to ✅ Open Source Edition   ✅ Express Edition   ✅ Professional Edition   ✅ Enterprise Edition

When using a custom type in jOOQ, you need to let jOOQ know about its associated org.jooq.Converter. Ad-hoc usages of such converters has been discussed in the chapter about data type conversionor ad-hoc converters. However, when mapping a custom type onto a standard JDBC type, a more common use-case is to let jOOQ know about custom types at code generation time.

Assuming you have a converter like this:

public class IntegerToYearConverter extends AbstractConverter<Integer, Year> {
    public IntegerToYearConverter() {
        super(Integer.class, Year.class);
    }

    @Override
    public Year from(Integer i) {
        return i == null ? null : Year.of(i);
    }

    @Override
    public Integer to(Year y) {
        return y == null ? null : y.getValue();
    }
}

The following example shows how to reference a custom Converter from your <forcedType> configuration:

XML (standalone and maven)
Programmatic
Gradle (Kotlin)
Gradle (Groovy)
Gradle (third party)
<configuration>
  <generator>
    <database>
      <forcedTypes>
        <forcedType>

          <!-- Specify the Java type of your custom type. This corresponds to the Converter's <U> type. -->
          <userType>java.time.Year</userType>

          <!-- Associate that custom type with your converter. -->
          <converter>com.example.IntegerToYearConverter</converter>

          <!-- Optionally specify whether the converter receives <T, U> type variables
               and Class<T>, Class<U> constructor arguments. Default is false. -->
          <genericConverter>false</genericConverter>
          <!-- A Java regex matching fully-qualified columns, attributes, parameters. Use the pipe to separate several expressions. -->
          <includeExpression>.*\.YEAR.*</includeExpression>
        </forcedType>
      </forcedTypes>
    </database>
  </generator>
</configuration>

See the configuration XSD, standalone code generation, and maven code generation for more details.

new org.jooq.meta.jaxb.Configuration()
  .withGenerator(new Generator()
    .withDatabase(new Database()
      .withForcedTypes(
        new ForcedType()

          // Specify the Java type of your custom type. This corresponds to the Converter's <U> type.
          .withUserType("java.time.Year")

          // Associate that custom type with your converter.
          .withConverter("com.example.IntegerToYearConverter")

          // Optionally specify whether the converter receives <T, U> type variables
          // and Class<T>, Class<U> constructor arguments. Default is false.
          .withGenericConverter(false)

          // A Java regex matching fully-qualified columns, attributes, parameters. Use the pipe to separate several expressions.
          .withIncludeExpression(".*\\.YEAR.*")
      )
    )
  )

See the configuration XSD and programmatic code generation for more details.

import org.jooq.meta.jaxb.*


configuration {
  generator {
    database {
      forcedTypes {
        forcedType {

          // Specify the Java type of your custom type. This corresponds to the Converter's <U> type.
          userType = "java.time.Year"

          // Associate that custom type with your converter.
          converter = "com.example.IntegerToYearConverter"

          // Optionally specify whether the converter receives <T, U> type variables
          // and Class<T>, Class<U> constructor arguments. Default is false.
          isGenericConverter = false

          // A Java regex matching fully-qualified columns, attributes, parameters. Use the pipe to separate several expressions.
          includeExpression = ".*\\.YEAR.*"
        }
      }
    }
  }
}

See the configuration XSD and gradle code generation for more details.

configuration {
  generator {
    database {
      forcedTypes {
        forcedType {

          // Specify the Java type of your custom type. This corresponds to the Converter's <U> type.
          userType = "java.time.Year"

          // Associate that custom type with your converter.
          converter = "com.example.IntegerToYearConverter"

          // Optionally specify whether the converter receives <T, U> type variables
          // and Class<T>, Class<U> constructor arguments. Default is false.
          genericConverter = false

          // A Java regex matching fully-qualified columns, attributes, parameters. Use the pipe to separate several expressions.
          includeExpression = ".*\\.YEAR.*"
        }
      }
    }
  }
}

See the configuration XSD and gradle code generation for more details.

generationTool {
  generator {
    database {
      forcedTypes {
        forcedType {

          // Specify the Java type of your custom type. This corresponds to the Converter's <U> type.
          userType = "java.time.Year"

          // Associate that custom type with your converter.
          converter = "com.example.IntegerToYearConverter"

          // Optionally specify whether the converter receives <T, U> type variables
          // and Class<T>, Class<U> constructor arguments. Default is false.
          genericConverter = false

          // A Java regex matching fully-qualified columns, attributes, parameters. Use the pipe to separate several expressions.
          includeExpression = ".*\\.YEAR.*"
        }
      }
    }
  }
}

See the configuration XSD and gradle code generation for more details.

For more details about how to match columns, please refer to the section about matching columns for forced types.

The above configuration will lead e.g. to AUTHOR.YEAR_OF_BIRTH being generated like this:

public class TAuthor extends TableImpl<TAuthorRecord> {

    // [...]
    public final TableField<TAuthorRecord, Year> YEAR_OF_BIRTH =    // [...]
    // [...]

}

This means that the bound type of <T> will be Year, wherever you reference YEAR_OF_BIRTH. jOOQ will use your custom converter when binding variables and when fetching data from java.sql.ResultSet:

// Get all date of births of authors born after 1980
List<Year> result =
create.selectFrom(AUTHOR)
      .where(AUTHOR.YEAR_OF_BIRTH.gt(Year.of(1980))
      .fetch(AUTHOR.YEAR_OF_BIRTH);

Feedback

Do you have any feedback about this page? We'd love to hear it!

The jOOQ Logo