Create object instances
There are different ways of creating new instances in the database. Instances might be created by inserting or appending an instance to the collection or by creating and filling a new instance and storing this to the database.
The typical way is creating an instance by calling insert() or append(). In some cases, this might, however, lead to unique key conflicts. When several unique keys have been defined for a collection, it often becomes easier to initialize an instance before adding it to the database.
When inserting/appending an instance for an owning collection (reference, owning extent or owning relationship) the key provided or extracted from the initialized instance will be checked. When already existing, the function throws an error. Otherwise, a new instance is created and stored to the database.
Many collections (relationships) have got an super set definition when being defined in the data model. Any collection, which is not the instance owner, usually needs a super set. When inserting or appending an instance to a collection with a super set, the create function first checks, whether an instance with the key passed to the function or extracted from the initialized instance does already exists in the super set. In this case, the instance to be inserted/appended to the subset is taken from the super set.
Finally, each set hierarchy ends up in an owning collection, which is the only place, where new instances might be created. When the instance to be created does nor exist in the top super set, in instance with the requires key will be created and added to the collection and all its super sets.
When a not owning relationship has been defined, which does not has got a super set, one cannot insert or append instances to this relationship. This is typically the case for inverse relationships (secondary), which are maintained by the system. In order to enable secondary inverse relationships (which should never be instance owner) to insert instances, a super set has to be defined.
In order to access instance attributes, an instance has to be selected in a property handle. Instances selected in a property handle might be new instances or instances stored already in the database.
When going to create a new instance, an initialized (not yet stored) instance can be selected in the property handle by calling initializeInstance(). After selecting an initialized instance, attributes can be be access, i.e. attribute values might be set. When unselecting the new instance in the property handle, it will be stored automatically. In order to avoid storing the instance, the selection has to be canceled (cancel()).
In order to store the instance properly in the database, at least key component attributes should be initialized properly. In order to store an instance in the database, save() should be called. When save is not called explicitly, the instance will be stored with the next request to change the selection in the property handle.
// create new instance
... fragment ( Property &person ) {
person.initializeInstance();
person.value("name") = "Miller";
person.value("first_name") = "Mary";
person.value("pid") = "P007";
person.value("birth_date") = "2010-05-31";
person.save(); // creates new instance in the database
}
In order to create new instances in the database one may also call insert() or append() with the appropriate access key value. In this case a new instance is created and stored in the database before being selected in the property handle. In this case you cannot avoid creating the instance unless you run creating the instance in a transaction.
In order to append an instance to the end of an unordered collection, append() should be called. When inserting instances into unordered collections, the new instance is inserted before the currently selected instance or at the position passed to the function.
Typically, object instances are inserted to a collection by key. When the collection is ordered, the key passed is the access key. When the collection is unordered, the passed key is considered to be the primary key.
While initializing the new instance, key components are moved to the instance before creating the instance. When inserting or appending an instance to a not owning collection, it is checked, whether an instance with the key passed does already exist in the superset or not. When such an instance could be located in the superset(s), it will be inserted to the current collection without creating a new instance.
When no such instance could be found, it depends on the property definition (schema definition), whether the instance will be created or not (PropertyDefinition::createAllowed()). When instance creation is not allowed, create() and append() will trow an exception. Otherwise, the instance will be created and added to the collection and its superset(s).
... fragment ( Property &person ) {
person.insert("P0010");
// now, the instance has been created and other attribute values might be set
person.value("name") = "Miller";
person.value("first_name") = "Mary";
// ...
person.save();
}
For owning and unordered collections (references, owning relationships), one may create new instances at a given position (insert()) in the collection or by appending (append()) an instance. The function creates a new (empty) instance and stores it to the database.
One may call insert() for a blank instance also for ordered collections In this case, key components have to be filled while initializing the instance, e.g. by using auto-numbering with an __AUTOIDENT key, but also by providing context handlers for initializing the new instance properly (doAfterInitialize() or doBeforeCreate()).
In order to create an instance only, when not yet existing, provide() might be called.
... fragment ( Property &person ) {
Property address(person,"address");
if ( address.count() == 0 )
address.append();
// same as: address.provide(0);
}
Blank instances cannot be created for not owning collections, even though those might be unordered, since a key is required in order to create the link to the instance in the superset. Since the new instance usually has got empty key component attributes, duplicate key condition will arraise.