8. Working with Heterogeneous Collections and References


Contents

8.1. Heterogeneous Collections

8.2. Heterogeneous References


8.1 Heterogeneous Collections

Heterogeneous collections are collections that can hold objects of multiple classes. The most common example of a heterogeneous collection is a collection that holds all subclasses of a base class. Heterogeneous collections can be defined using the mapping tool as part of an application schema. However, in the case of heterogeneous collections based on a base class or common interface there is no need to do so, as VBSF automatically creates heterogeneous collections at runtime for all base classes and interfaces that are referenced by the persistent classes in your schema. The only time you need to explicitly define a heterogeneous collection is when the classes in the collection are not related by a common superclass or interface.

To retrieve objects from a heterogeneous collection you must specify the name of the base class, common interface, or the name of the collection when invoking the standard get and list methods of the Database and OCollection classes. If VBSF automatically created the collection because one was not explicitly defined, then the name of the collection will be the fully qualified abstract class or interface name suffixed by the string 'Col'.

For example, if we have an abstract Customer class from which the Person and Organization concrete classes descended, then we would use the statement below to retrieve all concrete descendants of Customer:

Object[] all = db.get(Customer.class);


The above statement would retrieve both Person and Organization objects. Queries can also be formulated using the base class name:

OQuery qry = new OQuery(Customer.class);
qry.add(..);
Object[] all = qry.execute(db);


When executing queries on heterogeneous collections, you should use only query parameters for attributes common to all the classes in the collection.

In the above examples, if the Customer class was a concrete class instead of abstract, then the above statements would only retrieve objects of type Customer. In that case, if we wanted to retrieve all objects of type Customer, Person and Organization, then we would have to use the heterogeneous collection name as argument to the get method. Assuming that VBSF automatically created the collection, then the collection name would be the fully qualified base class name suffixed by the string 'Col', as shown in the example below:

Object[] all = db.get(Customer.class.getName() + "Col");


The Database and OCollection classes also provides the following additional methods specific to heterogeneous collections:

Object[] getForClass(String hCollName,String className);
Object[] getForClass(String hCollName, String className, BOP_Query query);
BORandomEnumeration getEnumerationForClass(String hCollName, String className);
BORandomEnumeration getEnumerationForClass(String hCollName, String className, BOP_Query query);
Object[] listForClass(String hCollName, String className);
Object[] listForClass(String hCollName, String className, BOP_Query query);
BOEnumeration listEnumerationForClass(String hCollName, String className);
BOEnumeration listEnumerationForClass(String hCollName, String className, BOP_Query query);


The above methods allow you to retrieve from a heterogeneous collection only objects of the supplied class name. For example, to retrieve only Person objects from the Customers collection, we would use the following statement:

Object[] allPersons = db.getForClass(Customer.class.getName(), Person.class.getName());


In the event that multiple objects of different classes that belong to the same heterogeneous collections have the same ID, and there is no explicit filter column, a heterogeneous collections will only return objects of the most concrete subclass. The only time multiple objects with the same ID may be returned is when the objects with the same ID do not have an inheritance relationship.

 

8.2 Heterogeneous References

A heterogeneous reference points to either a base class or an interface. If it points to a base class, it can reference an object of any type that is a subtype of the base type. If it points to an interface, it can reference an object of any type that implements that interface. Heterogeneous references return the most concrete class that matches the referenced ID, so a filter column is not necessary. However, a filter column does avoid querying the tables of all subtypes searching for the most concrete match. If you know the actual expected subtype, then you can also call the OReference.get(String className) or Database.getReference(Object holder, String refName, String className) methods, where className is the fully qualified name of the expected subtype.


The vposdemo and vshapesdemo sample applications provide many examples dealing with heterogeneous collections and references.

 

Next Section

Return to Table of Contents