Modelle und Metadaten
Kurzantwort: Jedes CDMS-Modell existiert zur Laufzeit in vier Ausprägungen – Entity (Persistenz), DTO (Antwort), CreatePayload/UpdatePayload (Eingabe) – plus einem MetaService, der Felder, Typen, Beziehungen, Regeln und Rollen beschreibt. Die Einordnung eines Modells als System, Tenant oder User entscheidet über Speicherort und Sichtbarkeit.
Die vier Ausprägungen eines Modells
Abschnitt betitelt „Die vier Ausprägungen eines Modells“flowchart LR
P["{Model}CreatePayload<br/>{Model}UpdatePayload"] -->|Payload2DtoMapper| D["{Model}Dto"]
D -->|Dto2EntityMapper| E["{Model}Entity"]
E -->|Entity2DtoMapper| D
M["{Model}MetaService<br/>Felder, Regeln, Rollen"] -.beschreibt.-> D
M -.beschreibt.-> E
| Klasse | Rolle |
|---|---|
{Model}Entity | JPA-Entity, Persistenzmodell |
{Model}Dto | Antwortmodell, trägt _reference gegen Zyklen |
{Model}CreatePayload | Eingabemodell für Create, ohne id |
{Model}UpdatePayload | Eingabemodell für Update, id ist Pflicht |
{Model}MetaService | ModelMetaInterface: MetaClassInfo + MetaFieldInfo je Feld |
Die Modell-Ebenen
Abschnitt betitelt „Die Modell-Ebenen“Drei @MappedSuperclass-Basisklassen entscheiden über Speicherort und Filter:
| Basisklasse | Speicherort | Zusatzfeld | Automatischer Filter |
|---|---|---|---|
AbstractSystemModel | System-Datenbank | – | keiner |
AbstractTenantModel | Tenant-Datenbank | – | Mandant (über die Datenbankwahl) |
AbstractUserModel | Tenant-Datenbank | _userId (not null, 36 Zeichen) | zusätzlich _userId = aktueller Benutzer |
Alle drei erben von AbstractEntityModel mit _createdOn, _updatedOn, einer
transienten _internalId und einem ID-basierten equals. Die ID ist immer eine
UUID, in der Datenbank als BINARY(16).
User ist keine eigene Datenbank. Die Benutzerebene ist eine Verfeinerung innerhalb der Mandantendatenbank; der Owner-Filter läuft im System-Layer.
Systemfelder
Abschnitt betitelt „Systemfelder“| Feld | Bedeutung | Wer setzt es |
|---|---|---|
id | UUID des Objekts | JPA beim Anlegen |
_createdOn | Anlagezeitpunkt | System-Layer beim Create |
_updatedOn | Änderungszeitpunkt | Persistenz |
_userId | Besitzer (nur AbstractUserModel) | System-Layer aus dem RequestContext |
_MODELTYPE | Diskriminator bei Vererbung | Persistenz/JPA |
_reference | Zyklusschutz während der Rekursion (nur DTO/Payload, nicht persistiert) | System-Layer |
Felder, die mit _ beginnen, überspringt die Rekursion beim Schreiben – der
Client kann sie nicht setzen.
Die Metadaten
Abschnitt betitelt „Die Metadaten“MetaClassInfo – pro Modell
Abschnitt betitelt „MetaClassInfo – pro Modell“| Feld | Bedeutung |
|---|---|
instanceable | false bei abstrakten Modellen |
audited | Modell führt Historie (Envers) und Dateiversionen |
environment | SYSTEM, TENANT oder USER |
name, packagePath, filePath | Namen und Pfade, filePath auch für die Dateiablage |
dtoClassReference, entityClassReference, createPayloadClassReference, updatePayloadClassReference | die vier Klassen |
createRole, readRole, updateRole, deleteRole, downloadRole, historyRole, rollbackRole | benötigte Rollen je Operation |
dtoChildReference, entityChildReference, payloadCreateChildReference, payloadUpdateChildReference | konkrete Untertypen bei Vererbung |
MetaFieldInfo – pro Feld
Abschnitt betitelt „MetaFieldInfo – pro Feld“| Feld | Bedeutung |
|---|---|
fieldName | Feldname |
relation, list | Beziehung? Liste oder Einzelreferenz? |
referenceType | ONETOONE, ONETOMANY, MANYTOONE, MANYTOMANY |
backReferenceFieldName | Feldname der Gegenseite |
simpleClassReference / dtoClassReference / entityClassReference | Zieltypen |
recursiveCreate, recursiveUpdate, recursiveDelete | erlaubte Rekursion über diese Beziehung |
createRole, readRole, updateRole, deleteRole | Feldrollen |
hooks | Feld-Hooks |
rules | MetaFieldRules – Validierungsregeln |
MetaFieldRules – Regeln je Feld
Abschnitt betitelt „MetaFieldRules – Regeln je Feld“notNullOnCreate, notNullOnUpdate, notEmpty, fieldLength, numberMin,
numberMax, stringPattern, unique, updatable, noCreate, defaultValue
sowie je Regel ein RuleScope (ALWAYS, CREATE, UPDATE). Details in
Validierung.
Die Modell-Annotationen
Abschnitt betitelt „Die Modell-Annotationen“Diese Annotationen beschreiben ein Modell in der Quelle bzw. im generierten Code
(cdms-commons):
| Annotation | Ziel | Wirkung |
|---|---|---|
@DataObject(apiPath, environment, type, root) | Klasse | Modell ist ein Wurzelobjekt; API-Pfad, SYSTEM/TENANT/USER, DATA/FILE |
@ExposeApi(create, read, update, patch, delete, query, download, history, rollback) | Klasse | welche Endpunkte erzeugt werden |
@AccessByRole(onCreate, onRead, onUpdate, onDelete, onDownload, onHistory, onRollback) | Klasse | benötigte Rollen |
@AccessByAttribute(attribute, field) | Klasse | Profilattribut muss Feldinhalt entsprechen |
@AccessFieldByRole(onCreate, onRead, onUpdate, onDelete) | Feld | Feldrollen |
@History(rollback) | Klasse | Auditing, optional mit Rollback |
@Singleton | Klasse | genau ein Objekt pro Scope |
@Reference(relation, backReferenceFieldName, recursive) | Feld | Beziehungstyp, Gegenseite, erlaubte Rekursion |
@Children(classPath, name) / @Childrens | Klasse | konkrete Untertypen |
@Unique | Feld | eindeutiger Wert |
@DefaultValue(value) | Feld | Vorbelegung beim Anlegen |
@NotNull(onCreate, onUpdate, notEmpty) | Feld | Pflichtfeld je Operation |
@FieldSize(size) | Feld | maximale Stringlänge |
@NumberMin(value, onCreate, onUpdate) / @NumberMax(...) | Feld | Zahlengrenzen |
@StringPattern(value, onCreate, onUpdate) | Feld | Regex |
@LargeTextData | Feld | großer Text (CLOB) |
@Decryption | Feld | Entschlüsselung in der Datenbank |
@Hook({...}) | Klasse/Feld | Hook-Implementierungen |
Feldtypen
Abschnitt betitelt „Feldtypen“Der Generator bildet CDMS-Feldtypen so auf Java ab:
| CDMS-Feldtyp | Java |
|---|---|
StringField, TextField, TextAreaField, PasswordField, EmailField, UrlField | String |
IntegerField, IntField | Integer |
LongField | Long |
DoubleField, NumberField | Double |
FloatField | Float |
BooleanField, CheckboxField | Boolean |
UUIDField | UUID |
DateField | LocalDate |
TimeField | LocalTime |
DateTimeField, TimestampField | LocalDateTime |
BigDecimalField, DecimalField | BigDecimal |
ByteArrayField, BinaryField | byte[] |
PrimitiveField | über das Attribut type im YAML |
Dateimodelle
Abschnitt betitelt „Dateimodelle“Ein Modell mit ClassType.FILE implementiert FileInterface:
name, mimeType, fileSize, fileVersion, fileId. Die Bytes liegen im
Storage, die Metadaten in der Datenbank – siehe
Dateien und Storage.
Singletons
Abschnitt betitelt „Singletons“Ein @Singleton-Modell hat pro Scope genau ein Objekt. Konsequenzen:
- kein Query-Endpunkt, keine ID in der URL
readliefert das eine Objekt,createschlägt fehl, wenn es schon existiert (object-already-exists|use-update)update/patchsetzen die intern ermittelte ID selbst ein- Typische Fälle: Tenant-Einstellungen, Benutzereinstellungen, Systemkonfiguration