Map API Read-Through

  GigaSpaces 5.X

Documentation Home
Quick Start Guide
Release Notes

Previous release

  Search Here
Searching GigaSpaces Platform 5.X Documentation

                                               

Summary: Client applications that use the Map API to read POJO data from a space and, if the data is not found in the space, require the space to read from a different datasource, which can be a database or any other type of external application.

Overview

This section discusses client applications that use the Map API to read POJO data from a space and, if the data is not found in the space, require the space to read from a different datasource, which can be a database or any other type of external application. The Map API read space operation results in a call to the CacheLoader Interface user implementation.
For each space get method of the Map API called in the client application (relevant for the get, remove, getAll operations), there must be a corresponding user implementation of CacheLoader Interface methods. The following sections describe in detail how to code these implementations with examples of each.

In case the external data source is a database, the HibernateCacheLoaderImpl/HibernateCacheStoreImpl driver may be used as an alternative that does not require any user implementation.

The examples of the CacheLoader method implementation in this section use the JDBC API to access RDBMS.

  • A full running example demonstrating the CacheLoader implementation using JDBC is located under: <GigaSpaces Root>\examples\Advanced\Data_Grid\Database-Integration\jdbcCaheStore.
  • A full running example demonstrating the CacheStore implementation using Hibernate is located under: <GigaSpaces Root>\examples\Advanced\Data_Grid\Database-Integration\HibernateCaheStore.
To enable logging for CacheLoader\Store, edit the <GigaSpaces Root>\config\gs_logging.properties file and set the persistent level to CONFIG or FINER.
For more details, refer to the Settings & Configuration section.

Reading a Single Object

This section discusses how to read or remove a single POJO object.

The IMap.remove operation execution is broken down at the space level into two separate calls: one to the CacheLoader.load method and one to the CacheStore.erase method.

This section focusses on the CacheLoader.load call. The write-through section discusses the CacheStore.erase method.

The figure illustrates how a client application reads a single Entry from the space where the actual data is loaded from a database or other external application.
The operation proceeds in two stages:

  1. The client application calls the IMap get or remove methods, passing the POJO object key as first parameter.
    The client application call would look like, for example:
    Person JohnDoe = (Person)IMap.get(person("john","doe", "0027"), waitForResponse);

    or

    Person JohnDoe = (Person)IMap.remove(person("john","doe", "0027"), waitForResponse);
  2. The Map API initiates data lookup in the space. If the Entry is found, it is returned to the client. If the Entry is not found, the CacheLoader Interface method load, is called by the space, passing a parameter IGSEntry that encapsulates the Entry data. The load method extracts the relevant data from the IGSEntry (such as class name) and, using the JDBC API, constructs a database SQL Query that gets the required record data from the database. The first object satisfying the query is converted to an IGSEntry object and returned back to the space. The space returns the result Entry in POJO format to the client implicitly.
    You can construct an IGSEntry object using the conversion methods.

CacheLoader.load Implementation

The CacheLoad Interface method load is called by the space and has the following signature:

Object loadedObject = load (IGSEntry key)

The object data is extracted from the IGSEntry key parameter using the MapEntry Interface:

IGSEntry.MapEntry mEntry =  key.getMapEntry();
Person key = (Person)mEntry.getKey();

The data from the individual properties of the Entry object can now be extracted and JDBC Query created to fetch the desired data from the database.

Sample Code

Client application: Map API :

public class Person  implements Serializable{
                String firstName;
                String lastName;
                int id;
                // must have empty constructor
                public Person(){}
 
                public Person(String firstName, String lastName, int id) {
                                this.firstName = firstName;
                                this.lastName = lastName;
                                this.id = id;
                }
 
                public String getFirstName() {return firstName;}
                public void setFirstName(String firstName) { this.firstName = firstName; }
                public int getId() {return id;}
                public void setId(int id) {this.id = id;}
                public String getLastName() {return lastName;}
                public void setLastName(String lastName) {  this.lastName = lastName;  }
}

The application code:

Person JohnDoe = IMap.get(person(null, null, 27), waitForResponse);

CacheLoader implementation: load method:

MyCacheLoader extends AbstractCacheLoader
{
	public Object load(Object key) {

		Object values[] = null;
		Person loaded_person = null;
		System.out.println(" ********* load " + key);
		Connection con = null;
		try {
			con = getConnection();
			int keyValue = 0;
			Map.Entry mEntry = ((IGSEntry) key).getMapEntry();

			if (mEntry != null) {
				keyValue = ((Integer) mEntry.getKey()).intValue();
			} else {
				keyValue = ((Integer) getId((IGSEntry) key)).intValue();
			}

			PreparedStatement stP = con.prepareStatement("select * from  " + 
			tableNames.get(Person.class.getName())
							+ " where ID = ? ");
			stP.setInt(1, keyValue);

			ResultSet rs = stP.executeQuery();
			int sz = rs.getMetaData().getColumnCount();

			values = new Object[sz];
			while (rs.next()) {
				for (int i = 0; i < sz; i++) {
					values[i] = rs.getObject(i + 1);
				}
				// HERE WE MAP table row to Person object
				loaded_person = new Person(String.valueOf(values[0]), String
						.valueOf(values[1]), Integer.valueOf(String
						.valueOf(values[2])));
				break;
			}
			rs.close();
			con.close();
			
		} catch (Exception e) {
			try {
				con.close();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
		return getConvertor().toIGSEntry(loaded_person);
	}
}

Reading Multiple Objects

This section describes how to read multiple POJO objects.

The figure illustrates how a client application reads a fixed number of POJO Entries from the space where the actual data is loaded from a database or other external application.
The operation proceeds in two stages:

  1. The client application calls the IMap getAll method, passing a collection of key objects as the parameter, where the keys correspond to the objects sought.
    The client application call would look like, for example:
    Map personMap  = IMap.getAll(personKeys);
  2. The Map API initiates data lookup in the space. Entries corresponding to keys in the collection that are found in the space are placed in a Map structure to return to the client. For each entry in the collection that was not found in the space, the space calls the CacheLoader Interface method load, passing the Entry's key in an IGSEntry object. The called method extracts the key object from the ISGEntry object and, using the JDBC methods, gets the required record data from the database. The record data is converted to an IGSEntry object and returned to the space. The space assembles the entry data for all keys and returns the data to the client as a Map of key-object Entries.
IMap.getAll(Collection keys) does not support a null value as the keys parameter.

CacheLoader.load Implementation

The CacheLoad Interface method load is called repeatedly by the space and has the following signature:

Object loadedObject = load (IGSEntry)

The object key data is extracted from the IGSEntry by:

key = IGSEntry.getKey()

The data from the individual properties of the Entry object can now be extracted and an SQLQuery created using the JDBC API.

Sample Code

Refer to the sample code above.

In client application: Map API Using POJO object:

Map personMap  = IMap.getAll(personKeys);

Special Read Operations

The following read operations can be used with the Map API.

  • Map API local Cache – CacheFinder with useLocalCache – Map API local Cache is scoped to the local cache (thus may reflect a partial space result).
    • keySet() – Returns a set view of the keys currently contained in the cache.
    • values() – Returns a collection view of the values contained in this cache.
    • containsKey(Object key) – Returns true if the cache contains the specified key.
  • GSMapImplCacheFinder without useLocalCacheGSMapImpl is a Map API over a space.
    • keySet()readMultiple of all map entities in space. Returns a set view of the keys currently contained in the space (or database).
    • values()readMultiple of all map entities in space. Returns a set view of the values currently contained in the space (or database).
    • containsKey(Object key) – read of specific map entity. Returns true if the space (or database) contains the specified key.

Wiki Content Tree


Your Feedback Needed!

We need your help to improve this wiki site. If you have any suggestions or corrections, write to us at techw@gigaspaces.com. Please provide a link to the wiki page you are referring to.

Labels

 
(None)