New versions: Dev (3.14)

Embedded domains

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

A very useful application of embeddable types are DOMAIN types. A DOMAIN type is a combination of:

  • A semantic type name
  • A data type (or other domain type)
  • A default value
  • A CHECK constraint

The combination name/type is enough to describe a semantic type like EMAIL across your schema, much better than e.g. VARCHAR(10). With embedded domains, you can generate a Java type for each domain type, and have that automatically attached to all your columns.

You can turn on the feature like this:

XML (standalone and maven)
Programmatic
Gradle
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.13.0.xsd">
  <generator>
    <database>
      <embeddableDomains>true</embeddableDomains>
    </database>
  </generator>
</configuration>
new org.jooq.meta.jaxb.Configuration()
  .withGenerator(new Generator()
    .withDatabase(new Database()
      .withEmbeddableDomains(true)
    )
  )
myConfigurationName(sourceSets.main) {
  generator {
    database {
      embeddableDomains = true
    }
  }
}

This will automatically produce an embeddable type configuration for each DOMAIN. For example, this schema:

CREATE DOMAIN email AS varchar(100);
CREATE DOMAIN year AS int;

CREATE TABLE user (
  id bigint NOT NULL PRIMARY KEY,
  name varchar(100) NOT NULL,
  email email NOT NULL,
  created year NOT NULL
);

The above would generate the following set of classes (simplified):

public class EmailRecord extends EmbeddableRecordImpl<EmailRecord> {
    public void setValue(String value) { ... }
    public String getValue() { ... }
    public EmailRecord() { ... }
    public EmailRecord(String value) { ... }
}

public class YearRecord extends EmbeddableRecordImpl<YearRecord> {
    public void setValue(Integer value) { ... }
    public Integer getValue() { ... }
    public YearRecord() { ... }
    public YearRecord(Integer value) { ... }
}

These classes are now referenced by embedded fields in the User table and UserRecord record (simplified):

public class User extends TableImpl<UserRecord> {
    public final TableField<UserRecord, Integer> ID;
    public final TableField<UserRecord, String> NAME;
    public final TableField<UserRecord, EmailRecord> EMAIL;
    public final TableField<UserRecord, YearRecord> CREATED;
}

With these generated fields, you can create semantically type safe queries:

create.insertInto(USER)
      .columns(USER.ID, USER.NAME, USER.EMAIL, USER.CREATED)
      .values(1, "domain_user", new EmailRecord("domain@user.com"), new YearRecord(2020))
      .execute();
The jOOQ Logo