Show/Hide Toolbars

TMS Aurelius Documentation

Navigation: Manipulating Objects

Memory Management

Scroll Prev Top Next More

Entity objects are saved and loaded to/from database using a TObjectManager object, which provides methods and properties for such operations. All entity objects cached in TObjectManager are managed by it, and you don't need to free such objects (unless you set OwnsObjects property to False). Also, entity objects retrieved from database, either loading by identifier or using queries, are also managed by the TObjectManager.

 

Concept of object state

 

In Aurelius when an object is told to be persistent (or cached, or managed) it means that the TObjectManager object is aware of that object and is "managing" it. When TObjectManager loads any object from the database, the object instances created in the loading process are persistent. You can also turn objects into persistent object when you for example call Save, Update or Merge methods.

 

When the TObjectManager is not aware of the object, the object is told to be transient (or uncached, or unmanaged).

 

Don't confuse a transient object with an object that is not saved into the database yet. You might have a TCustomer object which has been already saved in the database, but if the TCustomer instance you have is not being managed by the TObjectManager, it's transient.

 

Also, don't confuse persistent with saved. A persistent object means that TObjectManager is aware of it and it's managing it, but it might not be saved to the database yet.

 

Object lists

 

It's important to note that when retrieving object lists from queries, the list itself must be destroyed, although the objects in it are not. Note that when you use projections in queries, the objects returned are not entity objects, but result objects. In this case the objects are not managed by the object manager, but the list retrieved in result queries have their OwnsObjects set to true, so destroying the list will destroy the objects as well.

 

Unique instances

 

When dealing with entity objects (saving, loading, querying, etc.), object manager keeps an internal Identity Map to ensure that only one instance of each entity is loaded in the TObjectManager object. Each entity is identified by it's Id attribute. So for example, if you execute two different queries using the same object manager, and the query returns the same entity (same id) in the queries, the object instance in the both queries returned will be the same. The object manager will not create a different object instance every time you query the object. If you use a different TObjectManager object for each query, then you will have different instances of the same entity object

 

Examples

 

The code snippets below illustrates several the different situations mentioned above.

 

Saving objects

 

Customer := TTC_Customer.Create;
Customer.Name := 'Customer Name';
ObjectManager1.Save(Customer);
// From now on, you don't need to destroy Customer object anymore

// It will be destroyed when ObjectManager1 is destroyed

 

Loading objects

 

Customer := Manager1.Find<TCustomer>(CustomerId);
Customer2 := Manager1.Find<TCustomer>(CustomerId);
// Since CustomerId is the same for both queries, the same instance will be
// returned in Customer and Customer2 (Customer = Customer2), and you don't
// need to destroy such instance, it's manager by Manager1.

 

Retrieving entities from queries

 

Results := Manager.Find<TCustomer>
  .Add(Linq['Name'] = 'TMS Software')
  .List;
Results.Free;
// Results is a TObjectList<TCustomer> object that needs to be destroyed
// However, the object instances it holds are not destroyed and are kept 
// in Manager cache. The instances are also ensured to be unique in Manager context

 

Retrieving projected query results

 

Results := Manager.Find<TTC_Estimate>
  .CreateAlias('Customer''c')
  .Select(TProjections.ProjectionList
    .Add(TProjections.Sum('EstimateNo'))
    .Add(TProjections.Group('c.Name'))
    )
  .ListValues;
Results.Free;
// In this case the query does not return entity objects, but result objects (TCriteriaResult)
// Such result objects are not managed by TObjectManager. However, in this case,
// The Results object list is returned with its OwnsObjects property set to true. Thus, when
// you destroy Results object, the TCriteriaResult objects it holds will also be destroyed.

 

Using unmanaged objects

 

If for some reason you want to keep object instances available even after the object manager is destroyed (for example, after a query, you want to destroy object manager but keep the returned objects in memory), then just set the TObjectManager.OwnsObjects property to false:

 

Manager.OwnsObjects := false;
Results := Manager.Find<TCustomer>
  .Where(Linq['Name'] = 'TMS Software')
  .List;
Manager.Free;
// Now although Manager object was destroyed, all objects in Results list will be kept in memory, 
// EVEN if you destroy Results list itself later.