Interface TransientAttributeDefinition<T>

Type Parameters:
T - the attribute value type
All Superinterfaces:
AttributeDefinition<T>, ValueAttributeDefinition<T>

public sealed interface TransientAttributeDefinition<T> extends ValueAttributeDefinition<T>
An attribute that does not map to an underlying database column.

TransientAttributeDefinition extends ValueAttributeDefinition for attributes used for temporary data, UI state, calculated values, or any other data that should not be persisted to the database. They are initialized to null when entities are loaded and ignored during DML operations.

The value of transient attributes can be set and retrieved like normal attributes but are ignored during insert, update, and delete operations. By default, setting a transient value marks the entity as modified, but trying to update an entity with only transient values modified will result in an error.

Transient attributes are useful for UI state, temporary calculations and values the record carries without storing. They are editable fields wherever the framework builds components from attribute definitions, which is what makes them the way a form holds something the table does not store:

 public class Store extends DomainModel {

     interface Customer {
         EntityType TYPE = DOMAIN.entityType("store.customer");

         // Database columns
         Column<Integer> ID = TYPE.integerColumn("id");
         Column<String> FIRST_NAME = TYPE.stringColumn("first_name");
         Column<String> LAST_NAME = TYPE.stringColumn("last_name");
         Column<String> EMAIL = TYPE.stringColumn("email");

         // Transient attributes
         Attribute<String> FULL_NAME = TYPE.stringAttribute("full_name");
         Attribute<Boolean> SELECTED = TYPE.booleanAttribute("selected");
         Attribute<String> TEMP_NOTES = TYPE.stringAttribute("temp_notes");
         Attribute<Object> UI_STATE = TYPE.attribute("ui_state", Object.class);
     }

     void defineCustomer() {
         Customer.TYPE.as()
             .attributes(
                 // Database columns
                 Customer.ID.as()
                     .primaryKey(),
                 Customer.FIRST_NAME.as()
                     .column(),
                 Customer.LAST_NAME.as()
                     .column(),
                 Customer.EMAIL.as()
                     .column(),

                 // A derived attribute - NOT a transient one: computed from other attributes,
                 // and presented read-only. Shown here for contrast; see DerivedAttributeDefinition.
                 Customer.FULL_NAME.as()
                     .derived()
 				             .from(Customer.FIRST_NAME, Customer.LAST_NAME)
                     .with(values -> {
                         String first = values.get(Customer.FIRST_NAME);
                         String last = values.get(Customer.LAST_NAME);
                         return ((first != null ? first : "") + " " +
                                 (last != null ? last : "")).trim();
                     })
                     .caption("Full Name"),

                 // UI state attribute that doesn't modify entity
                 Customer.SELECTED.as()
                     .attribute()
                     .modifies(false) // Doesn't mark entity as modified
                     .defaultValue(false)
                     .caption("Selected"),

                 // Temporary notes (modifies entity by default)
                 Customer.TEMP_NOTES.as()
                     .attribute()
                     .caption("Temporary Notes"),

                 // Generic UI state storage
                 Customer.UI_STATE.as()
                     .attribute()
                     .modifies(false)
                     .caption("UI State"))
             .build();
     }
 }

 // Usage examples
 Entity customer = entities.entity(Customer.TYPE)
     .with(Customer.FIRST_NAME, "John")
     .with(Customer.LAST_NAME, "Doe")
     .with(Customer.EMAIL, "john@example.com")
     .build();

 // Transient attributes can be used for UI state
 customer.set(Customer.SELECTED, true);  // Doesn't mark entity as modified
 customer.set(Customer.TEMP_NOTES, "Important customer"); // Marks entity as modified

 // Derived transient values are computed automatically
 String fullName = customer.get(Customer.FULL_NAME); // "John Doe"

 // UI state storage
 customer.set(Customer.UI_STATE, new HashMap<String, Object>());

 // Transient attributes are ignored during database operations
 connection.insert(customer); // Only persists database columns

 // Check modification state
 boolean isModified = customer.modified(); // Only true if database columns changed
See Also:
  • Method Details

    • modifies

      boolean modifies()
      Returns:
      true if the value of this attribute being modified should result in a modified entity