Property definitions - fieldenms/tg GitHub Wiki
The central concept in TG is "entity", which consists of "properties". This article discusses structural aspects of property definitions with the main emphasis on deriving the metadata, used for database interactions.
Properties are fundamental constituent parts of entities that define their structure and define the relationships between entities. Properties carry the type information and the integrity constraints. Please refer to Entities and their validation for more details about integrity constraints.
In Java terms, a property is a field declared as part of an entity (descendant of AbstractEntity
) that is annotated with @IsProperty
, which has a getter and a setter (explicit or implicit).
All properties are classified according to the following essential criteria:
- Nature
-
Persistent - backed by a data storage, where property values can be saved to and retrieved from.
-
Transient - not backed by a data storage.
Typically used in synthetic and action entities, but also applicable to persistent entities. Transient properties are further categorised into:
- Calculated - usually read-only values, derived by computing the associated EQL expression.
- CritOnly - used to provide additional search criteria, hence application is limited to Synthetic Entities.
- Plain - all other transient properties, which can be used for intermediate state with all the benefits properties provide (e.g., integrity constraints).
- Type
- Entity - entity types.
- Collectional - represent a collection of values.
-
Primitive - types with a single component (e.g.,
String
,Integer
). -
Component - product types with one or more distinct attributes, where identity is defined by values of those attributes (e.g.
Money
,Kilometer
,Tonn
). - Special – a set of special types that do not fall into any of the above categories, introduced mainly as an implementation convenience, but also convey modelling aspects (see below for more details).
The following property types are supported by the platform.
Please refer to the Entity page.
Any type assignable to java.util.Collection
and parameterised with a type listed in items 1-3 (boxing of primitive types applies).
Additionally, any type assignable to Map
.
Types that represent what is considered to be an atomic value.
- Standard Java:
Long
,Integer
,BigDecimal
,Date
,String
,boolean
,Class
,Currency
,byte[]
. - Platform:
Colour
,Hyperlink
.
Component types represent values that have internal structure, but are not entities.
A component type is composed of one or more components.
For example, type Money
may be defined with 2 components:
amount : BigDecimal
currency : Currency
Component types provided by the platform are:
-
Money
-
RichText
Rich text cannot be used as a part of an entity key as it is not designed to have identity.
The are helper types. And there are currently only 2:
-
DynamicEntityKey
– a special type to represent compositekey
with one or more key members. -
NoKey
– a special type to represent propertykey
for action-entities that do have any practical use for a key.
Apart from the set of supported collection element types, the following rules apply to definitions of collectional properties:
- The field must be declared using the
final
modifier.
Entity definition must include a pair of accessor and setter methods for every declared property.
Accessor is synonymous with getter and serves the same purpose. The naming convention permits 2 kinds of prefixes immediately followed by the capitalised name of the property:
-
is
-- intended to be used withboolean
properties -
get
-- intended to be used with all other types of properties
In most cases an accessor method should simply return the property's value as-is.
However, for collectional properties an unmodifiable view should be returned to
facilitate immutability. The standard Collections
class provides a rich variety of methods
for this purpose.
Setter (also called mutator) is a method of a single argument that updates the
respective property's value. The only naming convention uses prefix set
followed
by the capitalised name of the property.
A setter method must be declared with public
or protected
visibility.
It is recommended to match the return type of a setter with the type of its declaring entity type,
in order to benefit from method chaining. This can be achieved by ending a setter's body with return this
.
All setter methods must be annotated with @Observable
in order to enable interception.
In most cases a setter method should update its property's value in a straightforward
manner -- by means of assignment. However, for collectional properties (which are final
)
it is required to first clear the collection and then add all elements of the argument.
@Observable
public Vehicle setParts(final List<Part> parts) {
this.parts.clear();
this.parts.addAll(parts);
return this;
}
Additionally, a property may admit a combination of the following characteristics:
-
Requiredness
Property must be assigned a value. After assignment, the value cannot be removed, only replaced.
-
KeyMembership
Property constitutes a part of its entity's key. Implies Requiredness.
-
OptionalKeyMembership
Requires KeyMembership, excludes Requiredness.
-
Finality
The first value that a property is persisted with remains unchanged for the whole lifetime of an entity.
-
...