Module is.codion.framework.domain
Interface Column.Generator<T>
- Type Parameters:
T
- the generated column type
- All Known Subinterfaces:
Column.Generator.Identity<T>
public static interface Column.Generator<T>
Generates column values for entities on insert.
Generators fall into two categories:
- Pre-insert generators - Fetch or generate the primary key value before the row is inserted
- Post-insert generators - The database automatically sets the primary key value on insert (identity columns, triggers)
Implementations should override either beforeInsert()
or afterInsert()
:
- If
inserted()
returns true, the primary key value is included in the insert statement andbeforeInsert(Entity, Column, DatabaseConnection)
(Entity, Column, DatabaseConnection)} should be used - If
inserted()
returns false, the database generates the primary key automatically andafterInsert(Entity, Column, DatabaseConnection, Statement)
should be used
Common key generator types and usage patterns:
public class Store extends DefaultDomain {
interface Customer {
EntityType TYPE = DOMAIN.entityType("store.customer");
Column<Integer> ID = TYPE.integerColumn("id");
}
interface Product {
EntityType TYPE = DOMAIN.entityType("store.product");
Column<Long> ID = TYPE.longColumn("id");
}
interface Order {
EntityType TYPE = DOMAIN.entityType("store.order");
Column<String> ID = TYPE.stringColumn("id");
}
void defineEntities() {
// Identity column (database auto-increment)
Customer.TYPE.define(
Customer.ID.define()
.primaryKey()
.generator(Generator.identity()))
.build();
// Sequence-based key generation (Oracle, PostgreSQL)
Product.TYPE.define(
Product.ID.define()
.primaryKey()
.generator(Generator.sequence("product_seq")))
.build();
// Custom query-based key generation
Order.TYPE.define(
Order.ID.define()
.primaryKey()
.generator(Generator.queried("SELECT 'ORD-' || NEXT VALUE FOR order_seq")))
.build();
}
}
// Custom key generator implementation
public class UUIDGenerator implements Generator<String> {
@Override
public void beforeInsert(Entity entity, Column<String> column, DatabaseConnection connection) {
// Only generate if not already set
if (entity.primaryKey().isNull()) {
String uuid = UUID.randomUUID().toString();
entity.set(column, uuid);
}
}
@Override
public boolean inserted() {
return true; // Include generated key in INSERT
}
}
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interface
Indicates an identity column based key generator. -
Method Summary
Modifier and TypeMethodDescriptiondefault void
afterInsert
(Entity entity, Column<T> column, DatabaseConnection connection, Statement insertStatement) Prepares the given entity after insert, that is, fetches automatically values and populates the column value in the entity.static <T> Column.Generator
<T> Instantiates a primary key generator which fetches automatically incremented column values after insert.default void
beforeInsert
(Entity entity, Column<T> column, DatabaseConnection connection) Prepares the given entity for insert, that is, generates and fetches any required values and populates the column value in the entity.default boolean
Specifies whether the insert statement should return the generated column values via the resultingStatement.getGeneratedKeys()
resultSet, accessible inafterInsert(Entity, Column, DatabaseConnection, Statement)
.static <T> Column.Generator.Identity
<T> identity()
Returns a column value generator based on an IDENTITY type column.default boolean
inserted()
The default implementation returns true.static <T> Column.Generator
<T> Instantiates a primary key generator which fetches primary key values using the given query prior to insert.static <T> Column.Generator
<T> Instantiates a primary key generator which fetches primary key values from a sequence prior to insert.
-
Method Details
-
inserted
default boolean inserted()The default implementation returns true.- Returns:
- true if the key value should be included in the insert query when entities using this key generator is inserted
-
beforeInsert
default void beforeInsert(Entity entity, Column<T> column, DatabaseConnection connection) throws SQLException Prepares the given entity for insert, that is, generates and fetches any required values and populates the column value in the entity. The default implementation does nothing, override to implement.- Parameters:
entity
- the entity about to be insertedconnection
- the connection to use- Throws:
SQLException
- in case of an exception
-
afterInsert
default void afterInsert(Entity entity, Column<T> column, DatabaseConnection connection, Statement insertStatement) throws SQLException Prepares the given entity after insert, that is, fetches automatically values and populates the column value in the entity. The default implementation does nothing, override to implement.- Parameters:
entity
- the inserted entityconnection
- the connection to useinsertStatement
- the insert statement- Throws:
SQLException
- in case of an exception
-
generatedKeys
default boolean generatedKeys()Specifies whether the insert statement should return the generated column values via the resultingStatement.getGeneratedKeys()
resultSet, accessible inafterInsert(Entity, Column, DatabaseConnection, Statement)
. The default implementation returns false.- Returns:
- true if the generated column values should be returned via the insert statement resultSet
- See Also:
-
sequence
Instantiates a primary key generator which fetches primary key values from a sequence prior to insert.// Oracle or PostgreSQL sequence Product.TYPE.define( Product.ID.define() .primaryKey() .generator(Generator.sequence("product_seq"))) .build(); // Usage - key is generated automatically Entity product = entities.entity(Product.TYPE) .with(Product.NAME, "Laptop") .with(Product.PRICE, new BigDecimal("999.99")) .build(); // Primary key will be fetched from sequence before insert connection.insert(product); Long generatedId = product.get(Product.ID); // e.g., 123
- Type Parameters:
T
- the generated column type- Parameters:
sequenceName
- the sequence name- Returns:
- a sequence based primary key generator
-
queried
Instantiates a primary key generator which fetches primary key values using the given query prior to insert.// Custom query-based key generation Order.TYPE.define( Order.ID.define() .primaryKey() .generator(Generator.queried("SELECT 'ORD-' || NEXT VALUE FOR order_seq"))) .build(); // Another example with date-based keys Invoice.TYPE.define( Invoice.ID.define() .primaryKey() .generator(Generator.queried( "SELECT FORMAT(GETDATE(), 'yyyyMMdd') + '-' + RIGHT('0000' + CAST(NEXT VALUE FOR invoice_seq AS VARCHAR), 4)"))) .build(); // Usage Entity order = entities.entity(Order.TYPE) .with(Order.CUSTOMER_FK, customer) .with(Order.TOTAL, new BigDecimal("150.00")) .build(); connection.insert(order); String generatedId = order.get(Order.ID); // e.g., "ORD-12345"
- Type Parameters:
T
- the generated column type- Parameters:
query
- a query for retrieving the column value- Returns:
- a query based column generator
-
automatic
Instantiates a primary key generator which fetches automatically incremented column values after insert.- Type Parameters:
T
- the generated column type- Parameters:
valueSource
- the value source, whether a sequence or a table name- Returns:
- an auto-increment based column value generator
-
identity
Returns a column value generator based on an IDENTITY type column.// SQL Server, MySQL auto-increment, or similar Customer.TYPE.define( Customer.ID.define() .primaryKey() .generator(Generator.identity())) .build(); // Usage - database generates the key Entity customer = entities.entity(Customer.TYPE) .with(Customer.NAME, "John Doe") .with(Customer.EMAIL, "john@example.com") .build(); // Primary key is null before insert Integer idBeforeInsert = customer.get(Customer.ID); // null // Database auto-generates the key during insert connection.insert(customer); // Primary key is now populated from database Integer generatedId = customer.get(Customer.ID); // e.g., 42
- Type Parameters:
T
- the generated column type- Returns:
- an identity based generated column value generator
- See Also:
-