Entity - fieldenms/tg GitHub Wiki

Table of Contents

  1. Introduction
  2. Domain Entities
  3. Value Entities
    1. PropertyDescriptor
    2. Union Entities
      1. Limitations
        1. Different key types in union members

Introduction

Technically speaking, any class that extends AbstractEntity is an entity type.

However, there are different intentions of creating entity types, which lead to further categorisation.

Domain Entities

Domain Entities represent a domain concept such as a vehicle, person, etc.

Such entities can be persistent or synthetic and their instances can exist in their own right. Action entities are also domain entities, but they cannot be property types.

Persistent and synthetic entities are product types, and represent a domain concept or an association between domain concepts.

Value Entities

Value Entities exist strictly to be used as property types for properties of a domain entity.

The two main representatives are: Union Entities and PropertyDescriptor.

PropertyDescriptor

PropertyDescriptor is an abstraction that reifies an entity property in a way that application users can benefit from.

For example, it is possible to model a configuration entity that could be used by users to designate properties of certain entity as required, or to assign some default values upon instantiation of those entities. Such configuration entity would have a property of type PropertyDescriptor, which can be represented as an autocompleter in the UI, and users would be able to search and select properties with a drop-down list.

Union Entities

Union Entities model sum types or tagged union. Their purpose is to hold a value that could take on several different, but fixed, persistent entity types, which are called union members. Only one union member can be in use at any one time, and an active property explicitly indicates, which member is in use. All union entity types must extend AbstractUnionEntity.

For example, domain entity Rotable can be in several "kinds" of locations – Workshop or Vehicle. This can be modelled as union entity Location with two properties: workshop: Workshop and vehicle: Vehicle, and the platform would guarantee that only one of those properties could have a value at the same time, and other kinds of support, such as EQL support, UI support, etc.

Limitations
Different key types in union members

All members of a union must have key types that are compatible from the EQL perspective. If this requirement is violated, a runtime exception during query execution should be expected.

For example, consider the following entity types:

class Vehicle extends AbstractEntity<...>
  Union union;

class Union extends AbstractUnionEntity
  Entity1 one;
  Entity2 two;

class Entity1 extends AbstractEntity<String>
  String key;

class Entity2 extends AbstractEntity<Integer>
  Integer key;

The following EQL query:

select(Vehicle.class).where().prop("union.key").isNull()

is expected to fail with:

ERROR: CASE types character varying and integer cannot be matched

which is due to the difference in key types in members of Union. I.e., Entity1.key : String is not compatible with Entity2.key : Integer.

In this context, compatibility of a set of types is defined as the existence of a common type such that each type in the set can be converted to.

Compatibilty can also be defined with the following relations:

<T> compatible(T, T)
<A, B> compatible(A, B) <=> compatible(B, A)
compatible(String, DynamicEntityKey)
<E extends AbstractEntity<KEY>, KEY> compatible(String, KEY) => compatible(String, E)
<E extends AbstractEntity<KEY>, KEY> compatible(DynamicEntityKey, KEY) => compatible(DynamicEntityKey, E)

On the other hand, if DynamicEntityKey is consistently used as the key type where possible, this limitation should never manifest.

⚠️ **GitHub.com Fallback** ⚠️