Fields
A field describes a property of a DataElement. These fields will be expanded to columns in a database table and fields in forms and are the basic content of a DataElement.
<dataElement name="Starship">
<fields>
<field name="field1"/>
<field name="field2"/>
</fields>
</dataElement>
Fields can either be ValueFields (basic attributes) or LinkFields (references to other DataElements).
ValueFields
ValueFields are simple fields that have a name
and a valueFieldType
. The ValueFieldType defines how the field is
stored and represented.
E.g. the following field will be represented and stored as a simple String:
<field name="address">
<fieldType>VALUE_FIELD</fieldType>
<valueField>
<valueFieldType component="" name="String"/>
</valueField>
</field>
There are several built-in ValueFieldTypes, but it also possible to define a ValueFieldType yourself.
Initial Values
Field
Causes a new UUID to be generated and stored in this field whenever a new instance is created. Use value "if_empty" to generate a UUID only if no value was passed to the create method in the details object.
<options>
<generateUuid/>
</options>
<options>
<generateUuid>if_empty</generateUuid>
</options>
LinkFields
LinkFields provide ways to link to another DataElement. They have a name
, a targetElement
and a linkFieldType
.
The target element is a reference to another DataElement. E.g. if you wish to link to an 'Employee' DataElement
<field name="employee">
<fieldType>LINK_FIELD</fieldType>
<linkField>
<targetElement component="administration" name="Employee"/>
<linkFieldType name="Ln01"/>
</linkField>
</field>
The LinkFieldType defines the multiplicity of the relationship.
There are 6 Link Field Types:
- Ln01: many-to-one, code-managed
- Ln02: many-to-one, JPA-managed
- Ln03: many-to-many, JPA-managed, owning side
- Ln04: one-to-many, JPA-managed
- Ln05: one-to-many, code-managed
- Ln06: many-to-many, JPA-managed, other side
Code-managed vs JPA-managed
When selecting a Link Field Type, you can choose between code-managed (Ln01 and Ln05) or JPA-managed (Ln02 and Ln04).
- Code-managed links will be generated as
Long
values in the Data layer. The generated code will then resolve the links through lookups. Code-managed links work for links between Components, since they do not require the tables to be in the same database or schema. - JPA-managed links are generated as references to JPA objects. The resolving is provided by the JPA implementation. JPA-managed links only work within Components, since other Components can have different schema's or databases.
Reverse Links
If you have a many-to-one link, you may want a one-to-many link in the other direction. There are some requirements to get this to work:
- The links should both be either code-managed (Ln01 and Ln05) or JPA-managed (Ln02 and Ln04).
- The many-to-one side (Ln01 or Ln02), should be named after the target DataElement (with first letter lowercase).
- The DataElement on the many side should also have a Finder defined, called
findBy{element}Eq
, where{element}
is the field on the one side.
Ln04 and Ln05 links need a reverse link to work.
Many-to-many Links
If you have an Ln03 (many-to-many) link and wish to add the reverse link, you can add an Ln06 link on the other Data Element. In this case, the name of the Ln03 field needs to be identical to the name of the element where the corresponding Ln06 link is specified, followed by the character “s”
One-to-one Links
There is currently no support for one-to-one links. The best option is to use Ln01 or Ln02 on one side.
Fields with specific behaviours
Some field names have specific behaviour. Creating a field with that name will also activate the corresponding feature.
Name
If a DataElement has a field name
, it should be a String. The name field is part of the DataRef for the DataElement,
meaning it can be used to identify an instance of that DataElement.
The name will also be used as a default representation in dropdowns.
If no name field is defined, an implicit name field will still be expanded, but the value of the name itself will be auto-generated.
It is possible to prevent this behaviour with the option nameNotWanted
, but be aware that this has far-reaching effects, as the option itself is a combinatorial effect.
Audit fields
Create/modify timestamps
The options audit.create.timestamp
and audit.modify.timestamp
can be used to track creation and modification
timestamps of instances of a DataElement. These are set in the data layer right before saving the instance to the
database.
Field
A field of type Date
or Timestamp
marked with this option will have the current timestamp stored in it when an
an instance of the element is created.
This option is implicitly added to a field with name enteredAt
if it is not explicitly defined on any other field in
the DataElement.
<options>
<audit.create.timestamp/>
</options>
Field
A field of type Date
or Timestamp
marked with this option will have the current timestamp stored in it when an
an instance of the element is modified. The timestamp is also stored when the instance is created as we consider this to
also be the first modification event in the scope of this functionality.
This option is implicitly added to a field with name lastModifiedAt
if it is not explicitly defined on any other field
in the DataElement.
<options>
<audit.modify.timestamp/>
</options>
Create/modify author
The options audit.create.author
and audit.modify.author
can be used to track who creates and modifies instances of a
DataElement. This is achieved using references to the account::User
element based on the contents of the active
UserContext
context group. These are set in the data layer right before saving the instance to the database. If no
UserContext
is present or no valid user data is stored within, the relevant field will be set to an empty value.
It may be possible to use this for links to elements other than account::User
, as the implementation supports Ln02
links as well as uses a generic DataRef
object constructed out of the information in UserContext
, but this is not
a recommended use-case!
Field
A link field of type Ln01
to account::User
marked with this option will have a reference to the user in the
UserContext
stored in it when an instance of the element is created.
This option is implicitly added to a field with name enteredBy
if it is not explicitly defined on any other field in
the DataElement.
<options>
<audit.create.author/>
</options>
Field
A link field of type Ln01
to account::User
marked with this option will have a reference to the user in the
UserContext
stored in it when an instance of the element is modified. The reference is also stored when the instance
is created as we consider this to also be the first modification event in the scope of this functionality.
This option is implicitly added to a field with name lastModifiedBy
if it is not explicitly defined on any other field
in the DataElement.
<options>
<audit.modify.author/>
</options>
Fields called enteredBy
or lastModifiedBy
should be Ln01
LinkFields to account::User
.
They will be automatically updated to the user that created (enteredAt) or last modified (lastModifiedAt) an instance.
Disabled
If a DataElement has a field disabled
, it should be a String.
The field will be used to 'soft delete' instances, meaning that instances will have disabled set to yes
when deleted, rather than be deleted from the table.
Soft deleted instances will be filtered out when executing finds.
It is also possible to use another field for this functionality by adding the cruds.softDelete
option.