close

Filter

loading table of contents...

Content Application Developer Manual / Version 2307

Table Of Contents

4.2.2.1 Association Types

There are a number of design trade offs for data views. Consider the forLinking data view of the page, which is a composition and thus creates a private instance for each child. This design avoids a cache lookup. Caching has an overhead and allocating a cache entry for a parent object with only one string property would cost more than it saves.

On the other hand, since you defined a cacheable default data view of a page anyway, you could consider reusing the parent’s default data view for the child:

<dataview appliesTo=”com.company.PageImpl”>
  <property name=”name”/>
  <property name=”description”/>
  <property name=”content”/>
  <property name=”parent” associationType=”aggregation”/>
</dataview>

An aggregation is different from a composition in that a cache lookup is performed for this property. All children would therefore share the same parent instance (provided it is not evicted from the cache). In this definition, a PageImpl would aggregate its parent which would again recursively aggregate its parent ... until null is reached (any data view for null is null). Since you expect parents to be frequently accessed anyway, it is OK to have them pulled into the cache by their children. The generated code is basically equivalent to the following:

class PageImpl$$ extends PageImpl {
  // null is the default data view
  PageImpl parent =
   (Page)dataviewFactory.lookupCached(super.getParent(), null);

  public Page getParent() {
    return this.parent;
  }
  ...
}

However, you also have to take the cache’s dependency tracking into consideration. When a data view reads a content object, a dependency is recorded. When a data view does a cache lookup for another data view, a dependency is recorded as well. Given the page definition above, a child page will therefore depend on its content object and onto its parent which itself has a dependency on its content object and so on. Thus, if you change the name of the root page, all page objects will be invalidated since they have transitively aggregated it.

There is an alternative solution. Instead of embedding the default data view of the parent, you can do the cache lookup on every access to the parent property. You avoid the dependency; instead you always read the latest version from the cache. This lazy lookup is achieved as follows:

<dataview appliesTo=”com.company.PageImpl”>
  <property name=”name”/>
  <property name=”description”/>
  <property name=”content”/>
  <property name=”parent” associationType=”static”/>
</dataview>

Defining a static association will make the caching system store which parent a page is associated with (the lightweight PageImpl instance that basically only holds the parent id), in place of its default data view (which contains the parent’s state). Instead, a cache lookup is done for the default data view whenever the parent property is retrieved. In Java code, this behavior looks like this:

class PageImpl$$ extends PageImpl {
  PageImpl parent = super.getParent();
  ...
  Page getParent() {
    return (Page)dataviewFactory.lookupCached(
       this.parent, null);
  }
  ...
}

A cache lookup is reasonably efficient to make this definition possible. You should, however, keep an eye on the number of lookups. A cache lookup requires thread synchronization, and too many synchronization requests might lead to contention.

One last thing needs mentioning: Properties that should not be cached are simply omitted from the data view definition. But what, if you still want to apply a data view to the property value? For this case, a “dynamic” association can be defined:

<property name=”randomPage” associationType=”dynamic”/>

With this definition, #getRandomPage() will be generated as follows:

class PageImpl$$ extends PageImpl {
  ...
 Page getRandomPage() {
    // invoke original impl, don’t cache
    Page p = super.getRandomPage();
    // cache lookup
    return (Page)dataviewFactory.lookupCached(
      p, null);
  }
  ...
}

Figure 4.1, “Phases of a data view lifecycle” shows, how data views are loaded and evaluated in the lifecycle of an HTTP request.

Phases of a data view lifecycle

Figure 4.1. Phases of a data view lifecycle


To recapitulate, if a property is an association to another bean, it is possible to apply a data view to that bean as well. There are four ways to do that:

Association Type Reference is stored in field Data view is applied at ... Cache Lookup Implies Cache dependency to
composition yes creation time no Content Bean and Data View
aggregation yes creation time yes Content Bean and Data View
static (default) yes property access yes Content Bean
dynamic no property access yes none

Table 4.2. Association types


Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.