loading table of contents...

4.2.2.4. Data Views for Experts

Data view design can be quite tricky. This section documents a very subtle pattern, injected aggregation, that should be omitted.

This problem occurs when you create beans that link to other beans that could be data views. Doing so, you will lose data view dependencies, because the data views are loaded outside of your bean.

Example

Take a Page bean, created in a controller and inject another content bean of type Linkable, called childBean. The Page bean has a getter method getTitle() that accesses the Linkable bean. The return value of the getter should be cached.

public class Page implements AssumesIdentity {
  private Linkable childBean;

  public void setLinkable(Linkable child) {
    this.childBean = child;
  }

  // not cached in dataview
  public Linkable getLinkable() {
    return this.childBean;
  }

  // cached in dataview!!!
  public String getTitle() {
    return this.childBean.getTitle();
  }

  public boolean equals(Object o) {...}

  public int hashCode() { ... }

  public void assumeIdentity(Object bean) {
    this.childBean = ((Page) bean).getLinkable();
  }
}

When the Page bean is created, it might be that the Linkable bean itself is a data view. If not, everything is fine. If you call Page#getTitle() a property dependency for Linkable is created. But, if the Linkable is a data view, no dependency is tracked:

The Page bean then acts like a data view that aggregates the Linkable. As a result, no property dependencies are generated if you call Page#getTitle(). Also, the Linkable is injected into the Page bean and therefore no data view dependency for the Linkable exists. As a result, the cached Page is not invalidated if the Linkable changes!

Solution

Do not access cached methods from a cached method or do not store the Linkable bean but the corresponding content object. Another method would be, to unwrap the Linkable data view into a normal LinkableImpl. You can use DataViewHelpers methods #isDataView() and #getOriginal() for that.