#932: EmployeeValidSinceAttrDO.kt

projectforge-business/src/main/kotlin/org/projectforge/business/fibu/EmployeeValidSinceAttrDO.kt Type: JPA Entity (Data Object) · Purpose: Time-dependent (validity-period) attributes for employees — status, annual leave, weekly hours · Path: projectforge-business/src/main/kotlin/org/projectforge/business/fibu/EmployeeValidSinceAttrDO.kt 186 lines · 133 code · 33 comments · 20 blank
Represents a single time-dependent attribute value for an employee that becomes valid from a specific date onward. Supports three types: STATUS, 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.

Architecture & Design

Type Polymorphism via String Value

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:

All transient accessors are annotated @CandHIgnore and @JsonIgnore — they are not part of the persistent or serialized model.

JPA Mapping

FieldDB ColumnTypeNotes
idpkLong (SEQUENCE)Primary key generated via hibernate_sequence.
employeeemployee_fkEmployeeDO (ManyToOne, LAZY)Not nullable. Uses @JsonIdentityReference(alwaysAsId=true).
typetypeEmployeeValidSinceAttrType? (STRING, max 30)Discriminator: STATUS, ANNUAL_LEAVE, or WEEKLY_HOURS.
validSincevalid_sinceLocalDateNot nullable. Date from which this attribute becomes effective.
valuevalueString (max 255)Type-dependent value stored as string (BigDecimal or enum name).
commentcommentString (LENGTH_TEXT)Optional free-text comment.

Named Queries

Copy Semantics

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.

History Integration

Implements CandHHistoryEntryICustomizer:

This 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.

Design Rationale

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.

Git History

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...