Domain Model and Data Structure
Entities and associations
The domain model is the contract that pages, microflows, security and integrations all rely on. Persistable entities are stored in the database; non-persistable entities live only in memory (typical for helper objects behind a page or objects passed to a Java action). Every persistable entity inherits system attributes - createdDate, changedDate, createdBy, changedBy and owner - maintained by the runtime, so modelling them yourself is a mistake.
Associations come in two flavours: reference (one-to-one, one-to-many) and reference set (many-to-many). A reference set is stored in a separate join table and cannot have delete behaviour configured; XPath that traverses reference sets is noticeably slower than traversing references. Generalization lets a specialization inherit the parent's attributes and associations, and an XPath constraint on the parent still returns the specializations.
Traps
- Validation rules (Required, Unique, Range, Regular expression) run at commit time in the runtime. A Unique rule is not a database constraint: concurrent commits can still create duplicates, and existing duplicates are not repaired.
- Calculated attributes are computed in memory on retrieval - they cannot be used in XPath constraints or in database-side sorting.
- Event handlers (before/after create, commit, delete) exist only on persistable entities; changes made in an after-commit handler are not persisted.
Rule of thumb
Model relationships as associations rather than storing an ID in a string attribute: associations give you delete behaviour, referential integrity and XPath traversal for free. If a question shows a foreign-key attribute being compared to another entity's ID, the intended answer is almost always "replace it with an association".