GlobalObjects
Lade ...
Suche ...
Keine Treffer
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 glo::Persistent) andere Objekte referenzieren sollen, müssen diese selbst auch persistent, das heißt von glo::Persistent 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 glo::TOndemand, glo::TOndemandList und glo::TOndemandSet).



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.



Eingebettete Objekte

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



Zeiger auf persistente Objekte

Objekte können über Zeiger als Attribut von einem persistenten Objekt genutzt werden. Über Zeiger referenzierte Objekte müssen von glo::Persistent 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 glo::EnDeepMode) 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 bei der Instanziierung des Objekts im Konstruktor dieser Zeiger auf nullptr gesetzt wird. Außerdem muss ein referenziertes Objekt im Destruktor mittels glo::Persistent::forget() aus dem Speicher entfernt werden.
Zusätzlich müssen der Kopie-Konstruktor und der Zuweisungsoperator dahingehend erweitert bzw. implementiert werden, dass beim Kopieren des Zeigers mittels glo::Persistent::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 glo::Persistent::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 glo::Persistent::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 glo::Persistent::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 persistente Objekte zu nutzen.



Intelligente Zeiger auf persistente Objekte (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 glo::Persistent 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 glo::EnDeepMode) 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 persistente Objekte.



Nachfrage-Zeiger auf persistente Objekte

Im Gegensatz zu einem Zeiger auf persistente Objekte (bei dem das referenzierte Objekt 'mitgeladen' wird), ist die glo::TOndemand 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 glo::TOndemand sinnvoll.
Durch setzen der TypeInfo im Schema auf dependent, kann ein referenziertes Objekt als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe glo::EnDeepMode) das referenzierte Objekt mitgespeichert bzw. mitgelöscht wird.



Zeiger-Container auf persistente Objekte

Objekte können über einen Container vom Typ glo::TPointerSet bzw. glo::TPointerList als Attribut von einem persistenten Objekt genutzt werden. Über diese Container referenzierte Objekte müssen von glo::Persistent 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 glo::EnDeepMode) 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 glo::TPointerSet 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 persistente Objekte.

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



Nachfrage-Zeiger-Container auf persistente Objekte

Im Gegensatz zu einer Zeiger-Container auf persistente Objekte (bei dem die referenzierten Objekte 'mitgeladen' werden), ist die glo::TOndemandList bzw. der glo::TOndemandSet 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 persistente Objekte).
Durch setzen der TypeInfo im Schema auf dependent, können die referenzierten Objekte als 'abhängig' gekennzeichnet werden. Dieses bewirkt, dass im Standardfall (siehe glo::EnDeepMode) die referenzierten Objekte mitgespeichert bzw. mitgelöscht wird.