EmployeeValidSinceAttrDO.ktSTATUS, ANNUAL_LEAVE, and WEEKLY_HOURS. Maps to t_fibu_employee_valid_since_attr with a composite unique constraint on (employee_fk, type, valid_since). Implements CandHHistoryEntryICustomizer for typed history rendering and WithHistory for automatic history tracking.Rather than using separate tables or columns for each attribute type, this entity uses a single value column (String) with a type discriminator. Transient properties provide type-safe access:
annualLeave — Getter/setter that validates type == ANNUAL_LEAVE and converts to/from BigDecimal.weeklyWorkingHours — Getter/setter that validates type == WEEKLY_HOURS and converts to/from BigDecimal.status — Getter/setter that validates type == STATUS and converts via EmployeeStatus.safeValueOf().All transient accessors are annotated @CandHIgnore and @JsonIgnore — they are not part of the persistent or serialized model.
| Field | DB Column | Type | Notes |
|---|---|---|---|
id | pk | Long (SEQUENCE) | Primary key generated via hibernate_sequence. |
employee | employee_fk | EmployeeDO (ManyToOne, LAZY) | Not nullable. Uses @JsonIdentityReference(alwaysAsId=true). |
type | type | EmployeeValidSinceAttrType? (STRING, max 30) | Discriminator: STATUS, ANNUAL_LEAVE, or WEEKLY_HOURS. |
validSince | valid_since | LocalDate | Not nullable. Date from which this attribute becomes effective. |
value | value | String (max 255) | Type-dependent value stored as string (BigDecimal or enum name). |
comment | comment | String (LENGTH_TEXT) | Optional free-text comment. |
EmployeeValidSinceAttr_FindByTypeAndDate — from EmployeeValidSinceAttrDO where employee.id=:employeeId and type=:type and validSince=:validSinceEmployeeValidSinceAttr_FindOtherByTypeAndDate — Same but with and id!=:id (for update validation excluding the current record).copyFrom(other) copies only validSince, value, and comment. Notably, type, id, and employee are NOT copied — this is because copy is used for the deleted-entry reuse pattern where an existing entry of the same type is updated with new values.
Implements CandHHistoryEntryICustomizer:
customize(historyEntry) method finds the "value" attribute in the history and sets its propertyTypeClass based on the type discriminator:
ANNUAL_LEAVE → BigDecimal::classWEEKLY_HOURS → BigDecimal::classSTATUS → EmployeeStatus::classThis ensures that history entries display the value field with the correct type formatting (e.g., "5.00" for BigDecimal, i18n label for enum) rather than as raw strings.
The "validity-period" pattern (also called "timeable attributes") allows employee attributes to change over time while maintaining a complete history. For example:
All changes are tracked as separate entries with validSince dates. The EmployeeCache and EmployeeServiceSupport resolve the current value by finding the latest entry whose validSince is on or before today's date.
868d6abb7 2025 -> 2026 feb661d79 Employee: displaying history for time attrs 63cc65ae0 Flyway stuff, Employee.timed-attrs 28efde264 Employee: weeklyWorkingHours now as time-dependent attr. 63081666f Source file headers: 2024-> 2025. 0237d5eba Json serialization refactored: IdOnlySerializer and IdsOnlySerializer introduced. 6aca64431 Migration stuff in progress... (all tests of all packages: OK). 4b9ffbee2 Migration stuff in progress... (all tests of all packages: OK). e80642c81 Migration stuff in progress... (all tests of all packages: OK). d6ad9ea38 Migration stuff in progress... 66ec668f6 Migration stuff in progress... 84e863624 Migration stuff in progress... (all tests of all packages: OK). b79a1edca Migration stuff in progress... (all tests of all packages: OK). d67bce18b Migration stuff in progress... 1faf30810 Migration stuff in progress... c8f8ed935 Declared all entities as FetchType.LAZY (was EAGER). 4c04cfd65 MAJOR-CHANGE! Migration of integer id's to Long id's 1be507bde Migration stuff in progress... ee106100c MIgration of timed attributes (employees and visitorbook) fdb15a1c1 Migration stuff in progress...