Application Composer Series: Object Relationships Explained
By Richard Bingham-Oracle on Jul 31, 2014
The post is accompanied by a new video on our YouTube channel, and through both we'll explain the key aspects of the relationship functionality available in Application Composer. You can find many of the basics covered in the Extending Sales guide, however as there are subtle differences in the functionality and how you choose to use it we'll highlight those key points that may affect the design of your customizations.
The ability to relate Business Objects together allows you to display and manage all the data required to meet a specific task. Standard objects are already seeded with relationships to provide basic features, such as the opportunities pages that allow you to see and add/edit not only the core opportunity data but also person records as contacts or team members and specify product items as revenue items. Similarly for your customizations and extensions you'll commonly want to link new fields and records with existing application data, such as existing person records to custom Service Requests records, and those Service Requests to your existing customers. You'll see related objects exposed on the UI either as a list of values (known as a choice list), a sub-tab region, or in a tree node display.
The joins feature is available for many Standard objects and allows you to use the underlying View Links to include additional fields from related objects on the pages of your parent object. As such if you are using standard objects then look at joins to support your requirements before creating unnecessary relationships. Check out this demo video for more on joins.
You can investigate the relationships that exist for any single object by visiting that objects overview page, as shown below.
You can create new relationships using three specific methods, and each one determines the properties of the resulting relationship:
- Implicitly by creating a Child Object from the parent object overview page. See this video.
- Implicitly by creating a Dynamic Choice List in the add custom fields page.
- Explicitly using the Create Relationship feature available from the Common Setup pane.
In the feature terminology the current context object (the 'one') is known as the "source object" and the related (usually 'many') object is known as the "target object". There are four relationship types available, each being determined by the creation method used:
- Standard. Standard Relationships are those seeded in the system between standard objects. You cannot add or edit standard relationships.
- Parent-Child. A child object is created and exists only in the context of the parent object. Child objects cannot be exposed in their own pages or work areas, only as a sub-tab region or tree node from its parent. You cannot change a child object to
a parent object after the child object has been created. Child objects can have only one parent object, but obviously a parent can have multiple children. Child objects always store the parent object ID in an automatically created field.
- Choice List. When you simply wish to add a field to a page that allows the user to select and associate just one record(s) of another object in an LOV, this is the simplest option. The choice list is added as a custom field to the object.
- Reference. Reference Relationships are those explicitly created between two objects using the Create Relationships page. This relationship is similar to dynamic choice lists however only provides the sub-tab or tree node interface for the end user, with no support for lists of values. You also cannot use child objects for Reference relationships and a reference relationship simply works by adding a new field to the target object to store the foreign key details.
There is some support for cascading deletes in Application Composer, so that should a parent object record be deleted all of its child records also get cleaned up. This automatically applies to Standard-type relationships seeded to represent Parent-Child objects (e.g. Opportunity to Opportunity Contacts), and to all new Parent-Child relationships created during customization.
Please note that at this time Application Composer does not support the deletion of either standard or custom object definitions themselves, or of the relationships. If you no longer need an object or relationship that has been published from a sandbox, it is recommended to adjust the Description fields so it is clear that it is obsolete.
The other relationships-types are for those objects that usually exist somewhat independently of each other, as one-to-many or many-to-one relationships, therefore if one
object is deleted the other remains unaffected. If the source object record is deleted then
at run time a dynamic choice list or sub-tab table will simply have no rows shown.
Also interestingly you can create a new relationship on a object with itself, useful for modelling your own hierarchy implementation.
In the screenshot below taken from the Relationships page (from Application Composer sidebar, under Common Setup) you can see the following examples:
- Opportunity to Account is a standard relationship between two seeded objects however because the Account is used elsewhere there is no cascade delete
- Opportunity to the custom Contract object is through a choice list hence without cascade delete.
- Opportunity to the custom child object Marketing Request includes cascade delete
- Opportunity to Opportunity Contact is a seeded relationship therefore of Standard type, however since it models the parent-child functionality it includes cascade delete
- Opportunity to Opportunity Revenue is the same, of Standard type with cascade delete
- Opportunity to Resource is a custom relationship created between standard objects to meet a specific requirement, hence is of Reference type without cascade delete.
Many to Many Relationships
Whilst not immediately obvious, it is possible to create a many-to-many relationship should your use-case require it. Here the related records from both objects store their primary identifiers in an intersection object and table. This is done by creating in intermediary child object which acts as the intersection table. In simple terms Object A is created, to which a child Object B is added. Then Object C is created for which a dynamic choice list field is added based on the records of Object B. Based on this Objects A and C now have a many-to-many relationship. Going forwards it is planned to release the feature to explicitly create many-to-many relationships for custom objects.
The following examples help illustrate when you'd consider using the different relationship types in preference to each other:
- Parent-Child relationships are useful to ensure deletion, however child objects can only be created and displayed in the context of the parent. This would be useful for extending the Customer standard object with new records that are relatively simple and are only ever applicable to customers, such as business certifications.
- Dynamic Choice List relationships provide a new field to quickly relate a single data record from another object (one-to-one), however includes no automated cascading delete feature. An example might be an extra internal contact derived from the standard resources object.
- Reference relationships allow mapping of any top level object to another, but unlike the dynamic choice list it doesn't support the use of child objects. This also requires the explicit addition of a sub-tab or tree node to permit record creation. This would be used in preference to choice lists where it's commonly required to choose multiple records with the source object (i.e. one to many).
Using Custom Code
During the process of creating a child object you can specify the "Child Collection Name" field. This provides an internal name for the set of child object records known as the Collection Accessor in Groovy and returns a row iterator object that contains useful processing records in your custom code extensions, using the utility methods such as first() and hasNext().
Whilst dynamic choice lists and reference relationships do not support automatic cascade delete, you can still implement similar functionality using Groovy. This would be through an Object Trigger based on the Before Remove trigger event and with associated code using a View Criteria to find the related records followed by the remove() method applied to each row.