GlobalObjects
Persistente Objekte referenzieren

Grundsätzliches

Ein Grundsatz in der objektorientierten Programmierung ist das Erstellen von eigenen Typen. Diese können von Klassen als Attribut eingebettet, direkt mittels Zeiger oder ggf. in Listen referenziert werden.
Wenn persistente Objekte (Klasse abgeleitet von GloPersistent) andere Objekte referenzieren sollen, müssen diese selbst auch persistent, das heißt von GloPersistent abgeleitet sein.
Es werden von GlobalObjcts für persistente Objekte Referenzen auf andere persistente Objekte wie Pointer, auch in Containern, auf andere Objekte in der Objektdatenbank zur Reverenznavigation angeboten. Es kann eingestellt werden, ob die referenzierten Objekte mit dem Objekt mitgeladen (instanziiert) werden oder erst beim Zugriff auf diese (siehe auch GloTOndemand, GloTOndemandList und GloTOndemandSet ).

Abhängige Objekte

Für referenzierte Objekte kann eine Abhängigkeit eingestellt werden (dependent) so dass diese z.B. mitgespeichert bzw. mit gelöscht werden. Zudem können Attribute von solch referenzierten Objekten als Index genutzt werden.

Eingebettetes Objekt

Objekte können als Attribut von einem persistenten Objekt genutzt werden. Eingebettete Objekte müssen von GloPersistent abgeleitet sein. Eingebettete Objekte werden automatisch mit dem einbettenden Objekt gespeichert, gesperrt, frei gegeben und gelöscht.

Zeiger auf ein persistentes Objekt

Objekte können über Zeiger als Attribut von einem persistenten Objekt genutzt werden. Über Zeiger referenzierte Objekte müssen von GloPersistent abgeleitet sein. Über Zeiger referenzierte Objekte werden mit dem referenzierenden Objekt aus der Objektdatenbank 'geladen'. Sie werden nicht automatisch mit dem referenzierenden Objekt gespeichert, gesperrt, frei gegeben oder gelöscht.
Durch setzen der TypeInfo im Schema auf dependent, kann ein referenziertes Objekt als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe GloEnDeepMode) das referenzierte Objekt mitgespeichert bzw. mitgelöscht wird.

Zu beachten
Wenn eine Klasse mit einem Zeiger auf ein persistentes Objekt erstellt wird, muss sichergestellt werden, dass dieser Zeiger bei der Instanziierung eines Objekts im ctor auf NULL (0) gesetzt wird. Außerdem muss ein ggf. referenziertes Objekt im dtor mittels GloPersistent::forget() aus dem Speicher entfernt werden.
Außerdem müssen der Kopie-Konstruktor und der Zuweisungsoperator dahingehend erweitert bzw. implementiert werden, dass beim Kopieren des Zeigers mittels GloPersistent::remember() dessen ' ReferenceCount' inkrementiert wird.
Achtung
Bei Zeigern ist darauf zu achten, dass es nicht zu einer gegenseitige Referenzierung von zwei verschiedenen Objekten über Zeiger kommt.
Persistente Objekte sind mit einem Referenzzähler ausgestattet (siehe auch GloPersistent::m_uiReferenceCount). Damit besteht durch gegenseitige Referenzierung die Möglichkeit, ungewollt eine zirkuläre Rekursion herbeizuführen. GlobalObjects achtet zwar darauf, dass beim Einlesen z.B. von Objekt 'A' sein referenziertes Objekt 'B' auch eingelesen wird und Objekt 'B' sein referenziertes Objekt 'A' nicht nochmals aus der Datenbank liest, sondern das schon eingelesene 'A' referenziert. Es kann aber nicht verhindert werden, dass diese Objekte nicht mehr aus dem Speicher entfernt werden.

Beispiel:
Objekt 'A' und Objekt 'B' referenzieren sich gegenseitig über einen Zeiger. Die Referenzierung wird im jeweiligen Destruktor aufgehoben, also beim 'Gegenüber' die Methode GloPersistent::forget() aufgerufen.
Objekt 'A' wird instantiiert ('A's ReferenceCount = 1). Von 'A' referenziertes Objekt 'B' wird instantiiert ('B's ReferenceCount = 1). Objekt 'B' referenziert ja nun 'A' und da es schon existiert, wird Objekt 'B' nur 'A's ReferenceCount auf 2 inkrementieren. Wird 'A' destruiert, sollte ja im Normalfall in 'A's Destruktor 'B's GloPersistent::forget() aufgerufen werden. Aber da 'A's ReferenceCount nur auf 1 dekrementiert wurde, wird dessen Destruktor gar nicht aufgerufen.

Lösung:
Es wird empfohlen, in diesen Fällen Nachfrage Zeiger auf ein persistentes Objekt zu nutzen.

Intelligenter Zeiger auf persistentes Objekt (std::shared_ptr)

Objekte können über einen intelligenten Zeiger vom Typ std::shared_ptr als Attribut von einem persistenten Objekt genutzt werden. Über intelligenten Zeiger referenzierte Objekte müssen von GloPersistent abgeleitet sein. Über intelligente Zeiger referenzierte Objekte werden mit dem referenzierenden Objekt aus der Objektdatenbank 'geladen'. Sie werden nicht automatisch mit dem referenzierenden Objekt gespeichert, gesperrt, frei gegeben oder gelöscht.
Durch setzen der TypeInfo im Schema auf (dependent, kann ein referenziertes Objekt als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe GloEnDeepMode) das referenzierte Objekt mitgespeichert bzw. mitgelöscht wird.

Achtung
Bei intelligenten Zeigern ist darauf zu achten, dass es nicht zu einer gegenseitige Referenzierung von zwei verschiedenen Objekten über Zeiger kommt. Ähnliche Problematik wie bei Zeiger auf ein persistentes Objekt.

Nachfrage Zeiger auf ein persistentes Objekt

Im Gegensatz zu einem Zeiger auf ein persistentes Objekt (bei dem das referenzierte Objekt 'mitgeladen' wird), ist die GloTOndemand eine Referenz über die Objekt-ID auf ein persistentes Objekt; es wird also nicht mit dem referenzierenden Objekt aus der Objektdatenbank geladen, sondern kann bei Bedarf 'nachgeladen' werden.
Sinnvoller Einsatz ist immer dann gegeben, wenn ein Objekt ein nicht im jeden Fall notwendig im Speicher verfügbares 'großes' Objekt referenziert.
Z.B. bei einer Bilderverwaltung könnte ein Bildobjekt textuelle Informationen, ein Thumpnail und ein 'große' Bild enthalten. Für einige Ansichten ist es evtl. aus Geschwindigkeitsgründen gar nicht sinnvoll bei jeder Anzeige das 'große' Bild mit aus der Objektdatenbank zu holen. Da wäre eine Referenz über ein GloTOndemand sinnvoll.
Durch setzen der TypeInfo im Schema auf (dependent, kann ein referenziertes Objekt als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe GloEnDeepMode) das referenzierte Objekt mitgespeichert bzw. mitgelöscht wird.

Zeigerliste bzw. -set auf persistente Objekte

Objekte können über einen Container vom Typ GloTPointerSet bzw. GloTPointerList als Attribut von einem persistenten Objekt genutzt werden. Über diese Container referenzierte Objekte müssen von GloPersistent abgeleitet sein. Über diese Container referenzierte Objekte werden mit dem referenzierenden Objekt aus der Objektdatenbank 'geladen'. Sie werden nicht automatisch mit dem referenzierenden Objekt gespeichert, gesperrt, frei gegeben oder gelöscht.
Durch setzen der TypeInfo im Schema auf (dependent, können die referenzierten Objekte als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe GloEnDeepMode) die referenzierten Objekte mitgespeichert bzw. mitgelöscht wird.

Zu beachten
Die in dem Container mit instanziierten Objekte müssen nicht vom referenzierenden Objekt aus dem Speicher entfernt werden, dieses erledigt der GloTPointerSet selbst.
Achtung
Bei Zeiger-Containern ist darauf zu achten, dass es nicht zu einer gegenseitige Referenzierung von zwei verschiedenen Objekten über Zeiger kommt. Sie auch Beschreibung unter Zeiger auf ein persistentes Objekt.

Lösung:
Es wird empfohlen, in diesen Fällen Nachfrage Zeigerliste auf persistente Objekte zu nutzen.

Nachfrage Zeigerliste bzw. -set auf persistente Objekte

Im Gegensatz zu einer Zeigerliste auf persistente Objekte bzw. einem Zeigerset auf persistente Objekte (bei dem die referenzierten Objekte 'mitgeladen' werden), ist die GloTOndemandList bzw. der GloTOndemandSet ein Container von Referenzen über die Objekt-ID auf persistente Objekt; es werden diese also nicht mit dem referenzierenden Objekt aus der Objektdatenbank geladen, sondern können bei Bedarf 'nachgeladen' werden.
Sinnvoller Einsatz ist immer dann gegeben, wenn ein Objekt mehrere, nicht im jeden Fall notwendig im Speicher verfügbare, 'große' Objekte referenzieren soll (siehe auch Nachfrage Zeiger auf ein persistentes Objekt).
Durch setzen der TypeInfo im Schema auf (dependent, können die referenzierten Objekte als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe GloEnDeepMode) die referenzierten Objekte mitgespeichert bzw. mitgelöscht wird.