GlobalObjects
Loading...
Searching...
No Matches
Referencing persistent objects

Basic information

One principle in object-oriented programming is to create your own types. These can be embedded by classes as attributes, referenced directly by pointers or, if necessary, in lists.
If persistent objects (class derived from glo::Persistent) are to reference other objects, these objects themselves must also be persistent, i.e. derived from glo::Persistent.
GlobalObjcts for persistent objects provides references to other persistent objects such as pointers, also in containers, to other objects in the object database for reference navigation. You can specify whether the referenced objects are loaded (instantiated) with the object or only when they are accessed (see also glo::TOndemand, glo::TOndemandList and glo::TOndemandSet).



Dependent objects

A dependency can be set for referenced objects so that they are saved or deleted with the referencing object. In addition, attributes of such referenced objects can be used as an index.



Embedded objects

Objects can be used as an attribute of a persistent object. Embedded objects must be derived from glo::Persistent. Embedded objects are automatically loaded, saved, locked, released and deleted with the embedding object.



Pointer to persistent objects

Objects can be used as an attribute of a persistent object via pointers. Objects referenced by pointers must be derived from glo::Persistent. Objects referenced by pointers are 'loaded' with the referencing object from the object database. They are not automatically saved, locked, released or deleted with the referencing object.
By setting the TypeInfo in the schema to dependent, a referenced object can be marked as 'dependent'. This has the effect that in the standard case (see glo::EnDeepMode) the referenced object is also saved or deleted.

Note
If a class is created with a pointer to a persistent object, you must ensure that this pointer is set to nullptr in the constructor when the object is instantiated. Also, a referenced object in the destructor must be removed from memory using glo::Persistent::forget(). Additionally, the copy constructor and the assignment operator must be extended respectively implemented so that when the pointer is copied with glo::Persistent::remember(), its ' ReferenceCount' is incremented.
Attention
With pointers, care must be taken to avoid mutual referencing of two different objects via pointers.
Persistent objects are equipped with a reference counter (see also glo::Persistent::m_uiReferenceCount). This makes it possible to inadvertently induce a circular recursion by mutual referencing. GlobalObjects makes sure that when object 'A' is read in, for example, its referenced object 'B' is also read in and object 'B' does not read its referenced object 'A' from the database again, but references the already read in 'A'. However, it cannot be prevented that these objects are no longer removed from the memory.

Example:
Object 'A' and object 'B' reference each other via a pointer. The referencing is removed in the respective destructor, i.e. the method glo::Persistent::forget() is called in the referenced object.
Object 'A' is instantiated ('A's ReferenceCount = 1). Object 'B' referenced by 'A' is instantiated ('B's ReferenceCount = 1). Object 'B' now references 'A' and since it already exists, object 'B' will only increment 'A's ReferenceCount to 2. If 'A' is destroyed, normally 'B's glo::Persistent::forget() should be called in 'A's destructor. But since 'A's ReferenceCount was only decremented to 1, its destructor is not called at all.

Solution:
It is recommended to use Ondemand pointer to persistent objects in these cases.



Smart pointers to persistent objects (std::shared_ptr)

Objects can be used as an attribute of a persistent object via a smart pointer of type std::shared_ptr. Objects referenced by intelligent pointers must be derived from glo::Persistent. Objects referenced by smart pointers are 'loaded' with the referencing object from the object database. They are not automatically saved, locked, released or deleted with the referencing object.
By setting the TypeInfo in the schema to dependent, a referenced object can be marked as 'dependent'. This has the effect that in the standard case (see glo::EnDeepMode) the referenced object is also saved or deleted.

Attention
With intelligent pointers, care must be taken to avoid mutual referencing of two different objects via pointers. Similar problem as with Pointer to persistent objects.



Ondemand pointer to persistent objects

In contrast to a Pointer to persistent objects (where the referenced object is 'also loaded'), the glo::TOndemand is a reference to a persistent object via the object ID; it is therefore not loaded with the referencing object from the object database, but can be 'reloaded' if required.
It is always useful if an object references a 'large' object that has not to be necessarily available in the memory.
For example, in an image management system, an image object could contain textual information, a thumpnail and a 'large' image. For some views, it may not make sense to retrieve the 'large' image from the object database every time an object is displayed. A reference via a glo::TOndemand would be useful.
By setting the TypeInfo in the schema to dependent, a referenced object can be marked as 'dependent'. This has the effect that in the standard case (see glo::EnDeepMode) the referenced object is also saved or deleted.



Pointer container to persistent objects

Objects can be used as attributes of a persistent object via a container of the type glo::TPointerSet or glo::TPointerList. Objects referenced via these containers must be derived from glo::Persistent. Objects referenced via these containers are 'loaded' with the referencing object from the object database. They are not automatically saved, locked, released or deleted with the referencing object.
By setting the TypeInfo in the schema to dependent, a referenced object can be marked as 'dependent'. This has the effect that in the standard case (see glo::EnDeepMode) the referenced object is also saved or deleted.

Note
The objects instantiated in the container do not have to be removed from memory by the referencing object, this is done by the glo::TPointerSet itself.
Attention
With pointer containers, care must be taken to avoid mutual referencing of two different objects via pointers. See also the description under Pointer to persistent objects.

Solution:
It is recommended that you use Ondemand pointer container to persistent objects in these cases.



Ondemand pointer container to persistent objects

In contrast to a Pointer container to persistent objects (in which the referenced objects are 'also loaded'), the glo::TOndemandList or glo::TOndemandSet is a container of references to persistent objects via the object ID; these are therefore not loaded not with the referencing object from the object database, but can be 'reloaded' if required.
It is always useful if an object is to reference several 'large' objects that are not to be necessarily available in memory (see also Ondemand pointer to persistent objects).
By setting the TypeInfo in the schema to dependent, the referenced objects can be marked as 'dependent'. This has the effect that in the standard case (see glo::EnDeepMode) the referenced objects are also saved or deleted.