Chapter 6. Odds and Ends

Table of Contents

6.1. IndexedDataProviderCache
6.2. Don't call record count
6.3. Seam Usage
6.4. DataValve and JSF
6.5. Executing code before a fetch

This sections covers any additional info not included anywhere else.

6.1. IndexedDataProviderCache

The IndexedDataProviderCache provides random access to provider data with look ahead caching to optimize querying and take advantage of data coherence. The best example of this is in the swing table which is included in one of the examples. A swing table model knows the number of rows of data that exist (which could be thousands or millions) and lets the user scroll across the whole dataset. This means that the user can select any record from the available dataset at any point in time. In this event, it would be fetched from the data provider and returned to the user. However, the user will probably end up fetching the next x number of objects from the dataset as the next x number of rows in the table are displayed. For this reason, the cache not only fetches the requested row, but the next n number of rows where n is the batch size defined by an attribute on the cache. The IndexedDataProviderCache keeps hold of these items since they may well be reused when the table is repainted or the user starts to scroll backwards or forwards a few records at a time. This cache is limited in size, and records will start to be ejected on a least recently used basis. The IndexedDataProviderCache can be used to randomly browse thousands of records with no startup time and efficient memory use since it doesn't read all the data in at once. (The delay at the start is due to the creation of the database, not the loading of all the data).

6.2. Don't call record count

You should not avoid calling fetchRecordCount from within the data provider. The most likely place you will call it is to determine whether there are more results to be returned. This can be an expensive call to count all records or rows of data from the source that should be avoided if possible. In the database data provider included, we fetch an extra row to see if there are more results after the set of rows we want. This extra row is then taken off the final results that are returned to the user.

6.3. Seam Usage

With DataValve you can subclass either a SeamJPaQueryDataset or a SeamJpaNativeDataset so you can use either a Ejbql or Native query for fetching data. Also, there are adapter classes that can be used instead which adapts the interface to look more like an EntityQuery so you can just substitute one for the other.

6.4. DataValve and JSF

DataValve-Faces is a module for working with DataValve in JSF. It provides a Expression Language (EL) parameter resolver so you can use EL expressions directly in your queries. It also provides visual components for creating a sort link for clickable sortable columns and a simple paginator class.

For an example of using the datavalve-faces module in a servlet environment using CDI and JSF, take a look at the cdi demo application in the samples directory.

6.5. Executing code before a fetch

There are many times you may want to execute some code prior to executing a fetch (either record count, or actual results). For example, you may want to clear and re-add your restrictions if you are manually adding them. The doPreFetch() in the AbstractDataProvider class allows you to execute code prior to a fetch.

Example 6.1. Setting up the query prior to fetching.

public class SomePersonSearchProvider extends HibernateProvider {

  private String firstName;
  private String lastName;
  
  @Override
  protected void doPreFetch() {
    getRestrictions().clear();
    addRestrictionStr("p.firstName like :param",firstName+"%",firstName);
    addRestrictionStr("p.lastName like :param",lastName+"%",lastName);   
  }
}