Configuration
Applies to ✅ Open Source Edition ✅ Express Edition ✅ Professional Edition ✅ Enterprise Edition
Embeddable types can be specified in the code generator configuration as follows:
<configuration> <generator> <database> <!-- For each type, one embeddable entry is required --> <embeddables> <embeddable> <!-- The optional catalog of the embeddable type (the catalog of the first matched table if left empty) --> <catalog/> <!-- The optional schema of the embeddable type (the schema of the first matched table if left empty) --> <schema>PUBLIC</schema> <!-- The name of the embeddable type --> <name>AUDIT</name> <!-- An optional, defining comment of an embeddable --> <comment>An audit record containing common audit fields.</comment> <!-- The name of the reference to the embeddable type. Defaults to <name/> if left blank --> <referencingName>AUDIT_REFERENCE</referencingName> <!-- An optional, referencing comment of an embeddable. Defaults to <comment/> if left blank --> <referencingComment>An audit record containing common audit fields.</referencingComment> <!-- A regular expression matching qualified or unqualified table names to which to apply this embeddable specification If left blank, this will apply to all tables --> <tables>.*</tables> <!-- A list of fields to match to an embeddable's attributes. Each field must match exactly one column in each matched table. A mandatory regular expression matches field names, whereas an optional name can be provided to define the embeddable attribute name. If no name is provided, then the first matched field's name will be taken --> <fields> <field><expression>CREATED_AT</expression></field> <field><expression>CREATED_BY</expression></field> <field><name>MODIFIED_AT</name><expression>MODIFIED_AT|CHANGED_AT</expression></field> <field><name>MODIFIED_BY</name><expression>MODIFIED_BY|CHANGED_BY</expression></field> </fields> </embeddable> <!-- A more minimal configuration might look like this --> <embeddable> <name>MONETARY_AMOUNT</name> <fields> <field><expression>AMOUNT</expression></field> <field><expression>CURRENCY</expression></field> </fields> </embeddable> </embeddables> </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() // For each type, one embeddable entry is required .withEmbeddables( new EmbeddableDefinitionType() // The optional catalog of the embeddable type (the catalog of the first matched table if left empty) .withCatalog("") // The optional schema of the embeddable type (the schema of the first matched table if left empty) .withSchema("PUBLIC") // The name of the embeddable type .withName("AUDIT") // An optional, defining comment of an embeddable .withComment("An audit record containing common audit fields.") // The name of the reference to the embeddable type. Defaults to <name/> if left blank .withReferencingName("AUDIT_REFERENCE") // An optional, referencing comment of an embeddable. Defaults to <comment/> if left blank .withReferencingComment("An audit record containing common audit fields.") // A regular expression matching qualified or unqualified table names to which to apply this embeddable specification // If left blank, this will apply to all tables .withTables(".*") // A list of fields to match to an embeddable's attributes. Each field must match exactly one column in each matched table. // A mandatory regular expression matches field names, whereas an optional name can be provided to define the embeddable // attribute name. If no name is provided, then the first matched field's name will be taken .withFields( new EmbeddableField() .withExpression("CREATED_AT"), new EmbeddableField() .withExpression("CREATED_BY"), new EmbeddableField() .withName("MODIFIED_AT") .withExpression("MODIFIED_AT|CHANGED_AT"), new EmbeddableField() .withName("MODIFIED_BY") .withExpression("MODIFIED_BY|CHANGED_BY") ), // A more minimal configuration might look like this new EmbeddableDefinitionType() .withName("MONETARY_AMOUNT") .withFields( new EmbeddableField() .withExpression("AMOUNT"), new EmbeddableField() .withExpression("CURRENCY") ) ) ) )
See the configuration XSD and programmatic code generation for more details.
import org.jooq.meta.jaxb.* configuration { generator { database { // For each type, one embeddable entry is required embeddables { embeddable { // The optional catalog of the embeddable type (the catalog of the first matched table if left empty) catalog = "" // The optional schema of the embeddable type (the schema of the first matched table if left empty) schema = "PUBLIC" // The name of the embeddable type name = "AUDIT" // An optional, defining comment of an embeddable comment = "An audit record containing common audit fields." // The name of the reference to the embeddable type. Defaults to <name/> if left blank referencingName = "AUDIT_REFERENCE" // An optional, referencing comment of an embeddable. Defaults to <comment/> if left blank referencingComment = "An audit record containing common audit fields." // A regular expression matching qualified or unqualified table names to which to apply this embeddable specification // If left blank, this will apply to all tables tables = ".*" // A list of fields to match to an embeddable's attributes. Each field must match exactly one column in each matched table. // A mandatory regular expression matches field names, whereas an optional name can be provided to define the embeddable // attribute name. If no name is provided, then the first matched field's name will be taken fields { field { expression = "CREATED_AT" } field { expression = "CREATED_BY" } field { name = "MODIFIED_AT" expression = "MODIFIED_AT|CHANGED_AT" } field { name = "MODIFIED_BY" expression = "MODIFIED_BY|CHANGED_BY" } } } // A more minimal configuration might look like this embeddable { name = "MONETARY_AMOUNT" fields { field { expression = "AMOUNT" } field { expression = "CURRENCY" } } } } } } }
See the configuration XSD and gradle code generation for more details.
configuration { generator { database { // For each type, one embeddable entry is required embeddables { embeddable { // The optional catalog of the embeddable type (the catalog of the first matched table if left empty) catalog {} // The optional schema of the embeddable type (the schema of the first matched table if left empty) schema = "PUBLIC" // The name of the embeddable type name = "AUDIT" // An optional, defining comment of an embeddable comment = "An audit record containing common audit fields." // The name of the reference to the embeddable type. Defaults to <name/> if left blank referencingName = "AUDIT_REFERENCE" // An optional, referencing comment of an embeddable. Defaults to <comment/> if left blank referencingComment = "An audit record containing common audit fields." // A regular expression matching qualified or unqualified table names to which to apply this embeddable specification // If left blank, this will apply to all tables tables = ".*" // A list of fields to match to an embeddable's attributes. Each field must match exactly one column in each matched table. // A mandatory regular expression matches field names, whereas an optional name can be provided to define the embeddable // attribute name. If no name is provided, then the first matched field's name will be taken fields { field { expression = "CREATED_AT" } field { expression = "CREATED_BY" } field { name = "MODIFIED_AT" expression = "MODIFIED_AT|CHANGED_AT" } field { name = "MODIFIED_BY" expression = "MODIFIED_BY|CHANGED_BY" } } } // A more minimal configuration might look like this embeddable { name = "MONETARY_AMOUNT" fields { field { expression = "AMOUNT" } field { expression = "CURRENCY" } } } } } } }
See the configuration XSD and gradle code generation for more details.
generationTool { generator { database { // For each type, one embeddable entry is required embeddables { embeddable { // The optional catalog of the embeddable type (the catalog of the first matched table if left empty) catalog {} // The optional schema of the embeddable type (the schema of the first matched table if left empty) schema = "PUBLIC" // The name of the embeddable type name = "AUDIT" // An optional, defining comment of an embeddable comment = "An audit record containing common audit fields." // The name of the reference to the embeddable type. Defaults to <name/> if left blank referencingName = "AUDIT_REFERENCE" // An optional, referencing comment of an embeddable. Defaults to <comment/> if left blank referencingComment = "An audit record containing common audit fields." // A regular expression matching qualified or unqualified table names to which to apply this embeddable specification // If left blank, this will apply to all tables tables = ".*" // A list of fields to match to an embeddable's attributes. Each field must match exactly one column in each matched table. // A mandatory regular expression matches field names, whereas an optional name can be provided to define the embeddable // attribute name. If no name is provided, then the first matched field's name will be taken fields { field { expression = "CREATED_AT" } field { expression = "CREATED_BY" } field { name = "MODIFIED_AT" expression = "MODIFIED_AT|CHANGED_AT" } field { name = "MODIFIED_BY" expression = "MODIFIED_BY|CHANGED_BY" } } } // A more minimal configuration might look like this embeddable { name = "MONETARY_AMOUNT" fields { field { expression = "AMOUNT" } field { expression = "CURRENCY" } } } } } } }
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.
The previous configuration, if matched correctly against relevant tables, produces the following org.jooq.EmbeddableRecord
implementations (abbreviated):
public class AuditRecord extends EmbeddableRecordImpl<AuditRecord> { public AuditRecord(Timestamp createdAt, Timestamp modifiedAt, String createdBy, String modifiedBy) { /* ... */ } // Getters, setters }
public class MonetaryAmountRecord extends EmbeddableRecordImpl<MonetaryAmountRecord> { public MonetaryAmountRecord(BigDecimal amount, String currency) { /* ... */ } // Getters, setters }
Assuming we have a TRANSACTIONS
table like this:
CREATE TABLE transactions ( id BIGINT NOT NULL PRIMARY KEY, created_at TIMESTAMP NOT NULL, modified_at TIMESTAMP, created_by VARCHAR(100) NOT NULL, modified_by VARCHAR(100) NOT NULL, -- Other columns here amount DECIMAL(18, 2) NOT NULL, currency VARCHAR(10) NOT NULL );
With the previous embeddable type definitions, we would get a table that looks like this:
public class Transactions extends TableImpl<TransactionsRecord> { // Field initialisations omitted for simplicity // The AUDIT embeddable and its physical fields that it represents public TableField<TransactionsRecord, Integer> ID; public TableField<TransactionsRecord, Timestamp> CREATED_AT; public TableField<TransactionsRecord, Timestamp> MODIFIED_AT; public TableField<TransactionsRecord, String> CREATED_BY; public TableField<TransactionsRecord, String> MODIFIED_BY; public TableField<TransactionsRecord, AuditRecord> AUDIT_REFERENCE; // The MONETARY_AMOUNT embeddable and its physical fields that it represents public TableField<TransactionsRecord, BigDecimal> AMOUNT; public TableField<DRecord, String> CURRENCY; public TableField<DRecord, MonetaryAmountRecord> MONETARY_AMOUNT;
Notice how the embeddable type is just an auxiliary column, which, by default, does not replace its underlying columns. In order to replace the underlying columns, use the <replaceFields/> flag
You can now work with the underlying columns, as always, or use the embeddable types instead:
create.insertInto(TRANSACTIONS) .columns(TRANSACTIONS.ID, TRANSACTIONS.AUDIT_REFERENCE, TRANSACTIONS.MONETARY_AMOUNT) .values( 1, new AuditRecord(Timestamp.valueOf("2000-01-01 00:00:00"), null, "user", null), new MonetaryAmountRecord(new BigDecimal("20.00"), "EUR")) .execute();
These columns can be used in all types of statements, including e.g. SELECT
, INSERT
, UPDATE
, DELETE
References to this page
Feedback
Do you have any feedback about this page? We'd love to hear it!