Module is.codion.framework.domain
Interface DerivedAttribute<T>
- Type Parameters:
T
- the value type
- All Superinterfaces:
Attribute<T>
An attribute which value is derived from one or more source attributes.
Derived attributes compute their values from other attributes within the same entity or from related entities. They provide calculated fields, formatting, concatenation, and other derived values without being stored in the database.
Derived attributes are defined using value providers that receive source values and compute the derived result:
public class Store extends DefaultDomain {
interface Customer {
EntityType TYPE = DOMAIN.entityType("store.customer");
Column<String> FIRST_NAME = TYPE.stringColumn("first_name");
Column<String> LAST_NAME = TYPE.stringColumn("last_name");
Column<String> EMAIL = TYPE.stringColumn("email");
Column<LocalDate> BIRTH_DATE = TYPE.localDateColumn("birth_date");
// Derived attributes
Attribute<String> FULL_NAME = TYPE.stringAttribute("full_name");
Attribute<String> DISPLAY_NAME = TYPE.stringAttribute("display_name");
Attribute<Integer> AGE = TYPE.integerAttribute("age");
Attribute<String> INITIALS = TYPE.stringAttribute("initials");
}
void defineCustomer() {
Customer.TYPE.define(
Customer.FIRST_NAME.define()
.column(),
Customer.LAST_NAME.define()
.column(),
Customer.EMAIL.define()
.column(),
Customer.BIRTH_DATE.define()
.column(),
// Simple concatenation
Customer.FULL_NAME.define()
.attribute()
.derived(Customer.FIRST_NAME, Customer.LAST_NAME)
.valueProvider(values -> {
String first = values.get(Customer.FIRST_NAME);
String last = values.get(Customer.LAST_NAME);
return (first != null ? first : "") + " " + (last != null ? last : "");
}),
// Complex formatting with multiple sources
Customer.DISPLAY_NAME.define()
.attribute()
.derived(Customer.FULL_NAME, Customer.EMAIL)
.valueProvider(values -> {
String fullName = values.get(Customer.FULL_NAME);
String email = values.get(Customer.EMAIL);
return fullName + " (" + email + ")";
}),
// Age calculation
Customer.AGE.define()
.attribute()
.derived(Customer.BIRTH_DATE)
.valueProvider(values -> {
LocalDate birthDate = values.get(Customer.BIRTH_DATE);
return birthDate != null ?
Period.between(birthDate, LocalDate.now()).getYears() : null;
}),
// Initials from names
Customer.INITIALS.define()
.attribute()
.derived(Customer.FIRST_NAME, Customer.LAST_NAME)
.valueProvider(values -> {
String first = values.get(Customer.FIRST_NAME);
String last = values.get(Customer.LAST_NAME);
String firstInitial = first != null && !first.isEmpty() ?
first.substring(0, 1).toUpperCase() : "";
String lastInitial = last != null && !last.isEmpty() ?
last.substring(0, 1).toUpperCase() : "";
return firstInitial + lastInitial;
}))
.build();
}
}
// Usage
Entity customer = entities.builder(Customer.TYPE)
.with(Customer.FIRST_NAME, "John")
.with(Customer.LAST_NAME, "Doe")
.with(Customer.EMAIL, "john.doe@example.com")
.with(Customer.BIRTH_DATE, LocalDate.of(1990, 5, 15))
.build();
// Derived values are computed automatically
String fullName = customer.get(Customer.FULL_NAME); // "John Doe"
String displayName = customer.get(Customer.DISPLAY_NAME); // "John Doe (john.doe@example.com)"
Integer age = customer.get(Customer.AGE); // Calculated age
String initials = customer.get(Customer.INITIALS); // "JD"
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interface
Responsible for providing values derived from other valuesstatic interface
Provides the source values from which to derive the value.Nested classes/interfaces inherited from interface is.codion.framework.domain.entity.attribute.Attribute
Attribute.AttributeDefiner<T>, Attribute.Type<T>
-
Method Summary
Methods inherited from interface is.codion.framework.domain.entity.attribute.Attribute
define, entityType, name, type