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:
<configuration> <generator> <database> <!-- Use regular expressions to match the domains that should be replaced by embeddables. --> <embeddableDomains>.*</embeddableDomains> </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() // Use regular expressions to match the domains that should be replaced by embeddables. .withEmbeddableDomains(".*") ) )
See the configuration XSD and programmatic code generation for more details.
import org.jooq.meta.jaxb.* configuration { generator { database { // Use regular expressions to match the domains that should be replaced by embeddables. embeddableDomains = ".*" } } }
See the configuration XSD and gradle code generation for more details.
configuration { generator { database { // Use regular expressions to match the domains that should be replaced by embeddables. embeddableDomains = ".*" } } }
See the configuration XSD and gradle code generation for more details.
generationTool { generator { database { // Use regular expressions to match the domains that should be replaced by embeddables. embeddableDomains = ".*" } } }
See the configuration XSD and gradle code generation for more details.
As always, when regular expressions are used, they are regular expressions with default flags.
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();
Feedback
Do you have any feedback about this page? We'd love to hear it!